From 26df552d55d241bc1fdd6c928cef68333b4a76d1 Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Sat, 6 Aug 2016 20:28:55 -0500 Subject: [PATCH 01/63] Add edit, delete, and topics:delete permissions for users acting on their own posts --- public/src/client/topic/posts.js | 4 +- src/categories/create.js | 2 +- src/privileges.js | 8 +- src/privileges/categories.js | 21 ++++ src/privileges/posts.js | 18 ++- src/privileges/topics.js | 32 +++++- src/socket.io/posts/tools.js | 12 +- src/topics/create.js | 2 + src/topics/posts.js | 4 +- src/topics/tools.js | 17 +-- src/upgrade.js | 107 +++++++++++++++++- .../admin/partials/categories/groups.tpl | 5 +- src/views/admin/partials/categories/users.tpl | 5 +- 13 files changed, 213 insertions(+), 24 deletions(-) diff --git a/public/src/client/topic/posts.js b/public/src/client/topic/posts.js index c656b899a2..d9011d530d 100644 --- a/public/src/client/topic/posts.js +++ b/public/src/client/topic/posts.js @@ -27,7 +27,9 @@ define('forum/topic/posts', [ data.privileges = ajaxify.data.privileges; data.posts.forEach(function(post) { post.selfPost = !!app.user.uid && parseInt(post.uid, 10) === parseInt(app.user.uid, 10); - post.display_moderator_tools = post.selfPost || ajaxify.data.privileges.isAdminOrMod; + post.display_edit_tools = (ajaxify.data.privileges.editOwnPosts && post.selfPost) || ajaxify.data.privileges.isAdminOrMod; + post.display_delete_tools = (ajaxify.data.privileges.editOwnPosts && post.selfPost) || ajaxify.data.privileges.isAdminOrMod; + post.display_moderator_tools = post.display_edit_tools || post.display_delete_tools; post.display_move_tools = ajaxify.data.privileges.isAdminOrMod; post.display_post_menu = ajaxify.data.privileges.isAdminOrMod || post.selfPost || ((app.user.uid || ajaxify.data.postSharing.length) && !post.deleted); }); diff --git a/src/categories/create.js b/src/categories/create.js index f80e78f24e..a42c260155 100644 --- a/src/categories/create.js +++ b/src/categories/create.js @@ -48,7 +48,7 @@ module.exports = function(Categories) { function(data, next) { category = data.category; - var defaultPrivileges = ['find', 'read', 'topics:read', 'topics:create', 'topics:reply', 'upload:post:image']; + var defaultPrivileges = ['find', 'read', 'topics:read', 'topics:create', 'topics:reply', 'edit', 'delete', 'upload:post:image']; async.series([ async.apply(db.setObject, 'category:' + category.cid, category), diff --git a/src/privileges.js b/src/privileges.js index 1f28a7cb91..cc1e4d48ed 100644 --- a/src/privileges.js +++ b/src/privileges.js @@ -8,6 +8,9 @@ privileges.userPrivilegeList = [ 'topics:read', 'topics:create', 'topics:reply', + 'edit', + 'delete', + 'topics:delete', 'upload:post:image', 'upload:post:file', 'purge', @@ -20,6 +23,9 @@ privileges.groupPrivilegeList = [ 'groups:topics:read', 'groups:topics:create', 'groups:topics:reply', + 'groups:edit', + 'groups:delete', + 'groups:topics:delete', 'groups:upload:post:image', 'groups:upload:post:file', 'groups:purge', @@ -33,4 +39,4 @@ require('./privileges/topics')(privileges); require('./privileges/posts')(privileges); require('./privileges/users')(privileges); -module.exports = privileges; \ No newline at end of file +module.exports = privileges; diff --git a/src/privileges/categories.js b/src/privileges/categories.js index ce2c30506e..96eaba84c4 100644 --- a/src/privileges/categories.js +++ b/src/privileges/categories.js @@ -23,6 +23,9 @@ module.exports = function(privileges) { {name: 'Access Topics'}, {name: 'Create Topics'}, {name: 'Reply to Topics'}, + {name: 'Edit Posts'}, + {name: 'Delete Posts'}, + {name: 'Delete Topics'}, {name: 'Upload Images'}, {name: 'Upload Files'}, {name: 'Purge'}, @@ -362,6 +365,15 @@ module.exports = function(privileges) { 'topics:reply': function(next) { groups.isMember(uid, 'cid:' + cid + ':privileges:topics:reply', next); }, + 'edit': function(next) { + groups.isMember(uid, 'cid:' + cid + ':privileges:edit', next); + }, + 'delete': function(next) { + groups.isMember(uid, 'cid:' + cid + ':privileges:delete', next); + }, + 'topics:delete': function(next) { + groups.isMember(uid, 'cid:' + cid + ':privileges:topics:delete', next); + }, mods: function(next) { user.isModerator(uid, cid, next); } @@ -380,6 +392,15 @@ module.exports = function(privileges) { 'groups:topics:reply': function(next) { groups.isMember(groupName, 'cid:' + cid + ':privileges:groups:topics:reply', next); }, + 'groups:edit': function(next) { + groups.isMember(groupName, 'cid:' + cid + ':privileges:groups:edit', next); + }, + 'groups:delete': function(next) { + groups.isMember(groupName, 'cid:' + cid + ':privileges:groups:delete', next); + }, + 'groups:topics:delete': function(next) { + groups.isMember(groupName, 'cid:' + cid + ':privileges:groups:topics:delete', next); + }, 'groups:topics:read': function(next) { groups.isMember(groupName, 'cid:' + cid + ':privileges:groups:topics:read', next); } diff --git a/src/privileges/posts.js b/src/privileges/posts.js index a0d06f3600..c946e8c744 100644 --- a/src/privileges/posts.js +++ b/src/privileges/posts.js @@ -30,6 +30,7 @@ module.exports = function(privileges) { isOwner: async.apply(posts.isOwner, pids, uid), 'topics:read': async.apply(helpers.isUserAllowedTo, 'topics:read', uid, cids), read: async.apply(helpers.isUserAllowedTo, 'read', uid, cids), + edit: async.apply(helpers.isUserAllowedTo, 'edit', uid, cids), }, next); } ], function(err, results) { @@ -41,7 +42,7 @@ module.exports = function(privileges) { for (var i=0; i postDeleteDuration * 1000)) { return callback(new Error('[[error:post-delete-duration-expired, ' + meta.config.postDeleteDuration + ']]')); @@ -234,10 +239,13 @@ module.exports = function(privileges) { return callback(null, {isLocked: true}); } - posts.isOwner(pid, uid, next); + async.parallel({ + owner: async.apply(posts.isOwner, pid, uid), + edit: async.apply(privileges.posts.can, 'edit', pid, uid) + }, next); }, - function(isOwner, next) { - next(null, {editable: isOwner}); + function(result, next) { + next(null, {editable: result.owner && result.edit}); } ], callback); } diff --git a/src/privileges/topics.js b/src/privileges/topics.js index d1c8958045..c54102c77e 100644 --- a/src/privileges/topics.js +++ b/src/privileges/topics.js @@ -22,6 +22,9 @@ module.exports = function(privileges) { async.parallel({ 'topics:reply': async.apply(helpers.isUserAllowedTo, 'topics:reply', uid, [topic.cid]), 'topics:read': async.apply(helpers.isUserAllowedTo, 'topics:read', uid, [topic.cid]), + 'topics:delete': async.apply(helpers.isUserAllowedTo, 'topics:delete', uid, [topic.cid]), + edit: async.apply(helpers.isUserAllowedTo, 'edit', uid, [topic.cid]), + 'delete': async.apply(helpers.isUserAllowedTo, 'delete', uid, [topic.cid]), read: async.apply(helpers.isUserAllowedTo, 'read', uid, [topic.cid]), isOwner: function(next) { next(null, !!parseInt(uid, 10) && parseInt(uid, 10) === parseInt(topic.uid, 10)); @@ -40,7 +43,7 @@ module.exports = function(privileges) { var locked = parseInt(topic.locked, 10) === 1; var isAdminOrMod = results.isAdministrator || results.isModerator; var editable = isAdminOrMod; - var deletable = isAdminOrMod || results.isOwner; + var deletable = isAdminOrMod || (results.isOwner && results['topics:delete'][0]); plugins.fireHook('filter:privileges.topics.get', { 'topics:reply': (results['topics:reply'][0] && !locked) || isAdminOrMod, @@ -53,7 +56,9 @@ module.exports = function(privileges) { isAdminOrMod: isAdminOrMod, disabled: disabled, tid: tid, - uid: uid + uid: uid, + editOwnPosts: results.edit[0], + deleteOwnPosts: results['delete'][0] }, callback); }); }; @@ -176,6 +181,29 @@ module.exports = function(privileges) { ], callback); }; + privileges.topics.canDelete = function(tid, uid, callback) { + topics.getTopicField(tid, 'cid', function(err, cid) { + if (err) { + return callback(err); + } + helpers.some([ + async.apply(user.isModerator, uid, cid), + async.apply(user.isAdministrator, uid), + function(next) { + async.parallel({ + owner: async.apply(topics.isOwner, tid, uid), + 'topics:delete': async.apply(helpers.isUserAllowedTo, 'topics:delete', uid, [cid]) + }, function(err, result) { + if (err) { + return next(err); + } + next(null, result.owner && result['topics:delete'][0]); + }); + } + ], callback); + }); + }; + privileges.topics.canEdit = function(tid, uid, callback) { privileges.topics.isOwnerOrAdminOrMod(tid, uid, callback); }; diff --git a/src/socket.io/posts/tools.js b/src/socket.io/posts/tools.js index bcb7e59642..dfc99ac2dc 100644 --- a/src/socket.io/posts/tools.js +++ b/src/socket.io/posts/tools.js @@ -28,6 +28,12 @@ module.exports = function(SocketPosts) { isAdminOrMod: function(next) { privileges.categories.isAdminOrMod(data.cid, socket.uid, next); }, + canEdit: function(next) { + privileges.posts.canEdit(data.pid, socket.uid, next); + }, + canDelete: function(next) { + privileges.posts.canDelete(data.pid, socket.uid, next); + }, favourited: function(next) { favourites.getFavouritesByPostIDs([data.pid], socket.uid, next); }, @@ -45,7 +51,9 @@ module.exports = function(SocketPosts) { results.posts.deleted = parseInt(results.posts.deleted, 10) === 1; results.posts.favourited = results.favourited[0]; results.posts.selfPost = socket.uid && socket.uid === parseInt(results.posts.uid, 10); - results.posts.display_moderator_tools = results.isAdminOrMod || results.posts.selfPost; + results.posts.display_edit_tools = results.canEdit; + results.posts.display_delete_tools = results.canDelete; + results.posts.display_moderator_tools = results.posts.display_edit_tools || results.posts.display_delete_tools; results.posts.display_move_tools = results.isAdminOrMod; callback(null, results); }); @@ -165,4 +173,4 @@ module.exports = function(SocketPosts) { }, callback); } -}; \ No newline at end of file +}; diff --git a/src/topics/create.js b/src/topics/create.js index a173c1d661..1b561cdcaa 100644 --- a/src/topics/create.js +++ b/src/topics/create.js @@ -292,6 +292,8 @@ module.exports = function(Topics) { postData.favourited = false; postData.votes = 0; + postData.display_edit_tools = true; + postData.display_delete_tools = true; postData.display_moderator_tools = true; postData.display_move_tools = true; postData.selfPost = false; diff --git a/src/topics/posts.js b/src/topics/posts.js index 6bdf103420..66fc39e926 100644 --- a/src/topics/posts.js +++ b/src/topics/posts.js @@ -141,7 +141,9 @@ module.exports = function(Topics) { var loggedIn = !!parseInt(topicPrivileges.uid, 10); topicData.posts.forEach(function(post) { if (post) { - post.display_moderator_tools = topicPrivileges.isAdminOrMod || post.selfPost; + post.display_edit_tools = topicPrivileges.isAdminOrMod || (post.selfPost && topicPrivileges['edit']); + post.display_delete_tools = topicPrivileges.isAdminOrMod || (post.selfPost && topicPrivileges['delete']); + post.display_moderator_tools = post.display_edit_tools || post.display_delete_tools; post.display_move_tools = topicPrivileges.isAdminOrMod && post.index !== 0; post.display_post_menu = topicPrivileges.isAdminOrMod || post.selfPost || ((loggedIn || topicData.postSharing.length) && !post.deleted); post.ip = topicPrivileges.isAdminOrMod ? post.ip : undefined; diff --git a/src/topics/tools.js b/src/topics/tools.js index fd5321eb6b..3975193f76 100644 --- a/src/topics/tools.js +++ b/src/topics/tools.js @@ -1,11 +1,12 @@ 'use strict'; -var async = require('async'), +var async = require('async'); - db = require('../database'), - categories = require('../categories'), - plugins = require('../plugins'), - privileges = require('../privileges'); +var db = require('../database'); +var categories = require('../categories'); +var meta = require('../meta'); +var plugins = require('../plugins'); +var privileges = require('../privileges'); module.exports = function(Topics) { @@ -32,10 +33,10 @@ module.exports = function(Topics) { if (!exists) { return next(new Error('[[error:no-topic]]')); } - privileges.topics.isOwnerOrAdminOrMod(tid, uid, next); + privileges.topics.canDelete(tid, uid, next); }, - function (isOwnerOrAdminOrMod, next) { - if (!isOwnerOrAdminOrMod) { + function (canDelete, next) { + if (!canDelete) { return next(new Error('[[error:no-privileges]]')); } Topics.getTopicFields(tid, ['tid', 'cid', 'uid', 'deleted', 'title', 'mainPid'], next); diff --git a/src/upgrade.js b/src/upgrade.js index dc4af652c9..f30021da4e 100644 --- a/src/upgrade.js +++ b/src/upgrade.js @@ -10,7 +10,7 @@ var db = require('./database'), schemaDate, thisSchemaDate, // IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema - latestSchema = Date.UTC(2016, 7, 5); + latestSchema = Date.UTC(2016, 8, 6); Upgrade.check = function(callback) { db.get('schemaDate', function(err, value) { @@ -682,6 +682,111 @@ Upgrade.upgrade = function(callback) { winston.info('[2016/08/05] Removing best posts with negative scores skipped!'); next(); } + }, + function(next) { + thisSchemaDate = Date.UTC(2016, 8, 6); + + if (schemaDate < thisSchemaDate) { + updatesMade = true; + winston.info('[2016/08/06] Granting edit/delete/delete topic on existing categories'); + + var groupsAPI = require('./groups'); + var privilegesAPI = require('./privileges'); + + db.getSortedSetRange('categories:cid', 0, -1, function(err, cids) { + async.eachSeries(cids, function(cid, next) { + privilegesAPI.categories.list(cid, function(err, data) { + var groups = data.groups; + var users = data.users; + + async.waterfall([ + function(next) { + async.eachSeries(groups, function(group, next) { + if (group.privileges['groups:topics:reply']) { + return async.parallel([ + async.apply(groupsAPI.join, 'cid:' + cid + ':privileges:groups:edit', group.name), + async.apply(groupsAPI.join, 'cid:' + cid + ':privileges:groups:delete', group.name) + ], function(err) { + if (!err) { + winston.info('cid:' + cid + ':privileges:groups:edit, cid:' + cid + ':privileges:groups:delete granted to gid: ' + group.name); + } + + return next(err); + }); + } + + next(null); + }, next); + }, + function(next) { + async.eachSeries(groups, function(group, next) { + if (group.privileges['groups:topics:create']) { + return groupsAPI.join('cid:' + cid + ':privileges:groups:topics:delete', group.name, function(err) { + if (!err) { + winston.info('cid:' + cid + ':privileges:groups:topics:delete granted to gid: ' + group.name); + } + + return next(err); + }); + } + + next(null); + }, next); + }, + function(next) { + async.eachSeries(users, function(user, next) { + if (user.privileges['topics:reply']) { + return async.parallel([ + async.apply(groupsAPI.join, 'cid:' + cid + ':privileges:edit', user.uid), + async.apply(groupsAPI.join, 'cid:' + cid + ':privileges:delete', user.uid) + ], function(err) { + if (!err) { + winston.info('cid:' + cid + ':privileges:edit, cid:' + cid + ':privileges:delete granted to uid: ' + user.uid); + } + + return next(err); + }); + } + + next(null); + }, next); + }, + function(next) { + async.eachSeries(users, function(user, next) { + if (user.privileges['topics:create']) { + return groupsAPI.join('cid:' + cid + ':privileges:topics:delete', user.uid, function(err) { + if (!err) { + winston.info('cid:' + cid + ':privileges:topics:delete granted to uid: ' + user.uid); + } + + return next(err); + }); + } + + next(null); + }, next); + } + ], function(err) { + if (!err) { + winston.info('-- cid ' + cid + ' upgraded'); + } + + next(err); + }); + }); + }, function(err) { + if (err) { + return next(err); + } + + winston.info('[2016/08/06] Granting edit/delete/delete topic on existing categories - done'); + Upgrade.update(thisSchemaDate, next); + }); + }); + } else { + winston.info('[2016/08/06] Granting edit/delete/delete topic on existing categories - skipped!'); + next(); + } } // Add new schema updates here // IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema IN LINE 24!!! diff --git a/src/views/admin/partials/categories/groups.tpl b/src/views/admin/partials/categories/groups.tpl index eb432bfd27..ff2558bd20 100644 --- a/src/views/admin/partials/categories/groups.tpl +++ b/src/views/admin/partials/categories/groups.tpl @@ -10,8 +10,11 @@
  • Access Topics
  • Create Topics
  • Reply to Topics
  • +
  • Edit Posts
  • +
  • Delete Posts
  • +
  • Delete Topics
  • {groups.displayName} - \ No newline at end of file + diff --git a/src/views/admin/partials/categories/users.tpl b/src/views/admin/partials/categories/users.tpl index 9ec7c262fd..c97d452d5d 100644 --- a/src/views/admin/partials/categories/users.tpl +++ b/src/views/admin/partials/categories/users.tpl @@ -10,10 +10,13 @@
  • Access Topics
  • Create Topics
  • Reply to Topics
  • +
  • Edit Posts
  • +
  • Delete Posts
  • +
  • Delete Topics
  • Moderator
  • {users.username} - \ No newline at end of file + From 6d1a37d9af6a27c30b7076c9f0b4efe7655aa57c Mon Sep 17 00:00:00 2001 From: barisusakli Date: Tue, 9 Aug 2016 10:49:09 +0300 Subject: [PATCH 02/63] up composer --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7d28c8e598..db81ffb92d 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "morgan": "^1.3.2", "mousetrap": "^1.5.3", "nconf": "~0.8.2", - "nodebb-plugin-composer-default": "4.1.5", + "nodebb-plugin-composer-default": "4.1.6", "nodebb-plugin-dbsearch": "1.0.2", "nodebb-plugin-emoji-extended": "1.1.1", "nodebb-plugin-emoji-one": "1.1.5", From b3b2d81b8c16072e80c146d5e7252a3dfc403b0a Mon Sep 17 00:00:00 2001 From: barisusakli Date: Tue, 9 Aug 2016 14:43:23 +0300 Subject: [PATCH 03/63] up composer --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index db81ffb92d..8523785316 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "morgan": "^1.3.2", "mousetrap": "^1.5.3", "nconf": "~0.8.2", - "nodebb-plugin-composer-default": "4.1.6", + "nodebb-plugin-composer-default": "4.1.7", "nodebb-plugin-dbsearch": "1.0.2", "nodebb-plugin-emoji-extended": "1.1.1", "nodebb-plugin-emoji-one": "1.1.5", From 9856cf282a8e0a9c65127deddf2a7da7701282b7 Mon Sep 17 00:00:00 2001 From: NodeBB Misty Date: Tue, 9 Aug 2016 09:02:34 -0400 Subject: [PATCH 04/63] Latest translations and fallbacks --- public/language/ar/register.json | 2 +- public/language/ar/user.json | 2 +- public/language/nl/login.json | 2 +- public/language/nl/topic.json | 2 +- public/language/sl/category.json | 12 +++---- public/language/sl/email.json | 34 ++++++++++---------- public/language/sl/error.json | 34 ++++++++++---------- public/language/sl/global.json | 4 +-- public/language/sl/pages.json | 2 +- public/language/sl/tags.json | 2 +- public/language/sl/topic.json | 44 +++++++++++++------------- public/language/sl/uploads.json | 8 ++--- public/language/sl/user.json | 54 ++++++++++++++++---------------- 13 files changed, 101 insertions(+), 101 deletions(-) diff --git a/public/language/ar/register.json b/public/language/ar/register.json index 3c61bf8b34..c6ccf2231e 100644 --- a/public/language/ar/register.json +++ b/public/language/ar/register.json @@ -1,6 +1,6 @@ { "register": "تسجيل", - "cancel_registration": "Cancel Registration", + "cancel_registration": "إلغاء التسجيل", "help.email": "افتراضيا، سيتم إخفاء بريدك الإلكتروني من العامة.", "help.username_restrictions": "اسم مستخدم فريدة من نوعها بين1% و2% حرفا. يمكن للآخرين ذكرك @ <'span id='your-username> اسم المستخدم .", "help.minimum_password_length": "كلمة المرور يجب أن تكون على الأقل بها 1% أحرف", diff --git a/public/language/ar/user.json b/public/language/ar/user.json index 6d6b236865..0654ea0a71 100644 --- a/public/language/ar/user.json +++ b/public/language/ar/user.json @@ -6,7 +6,7 @@ "postcount": "عدد المشاركات", "email": "البريد الإلكتروني", "confirm_email": "تأكيد عنوان البريد الإلكتروني", - "account_info": "Account Info", + "account_info": "معلومات الحساب", "ban_account": "Ban Account", "ban_account_confirm": "هل تريد حقاً حظر هاذا العضو؟", "unban_account": "Unban Account", diff --git a/public/language/nl/login.json b/public/language/nl/login.json index 9704cc7ce7..e6d21e1fa6 100644 --- a/public/language/nl/login.json +++ b/public/language/nl/login.json @@ -8,5 +8,5 @@ "failed_login_attempt": "Aanmelden mislukt", "login_successful": "Je bent succesvol ingelogd!", "dont_have_account": "Geen gebruikersaccount?", - "logged-out-due-to-inactivity": "You have been logged out of the Admin Control Panel due to inactivity" + "logged-out-due-to-inactivity": "Je bent uitgelogt van het admin control panel vanwege inactiviteit." } \ No newline at end of file diff --git a/public/language/nl/topic.json b/public/language/nl/topic.json index d938fb6c50..337f02bbea 100644 --- a/public/language/nl/topic.json +++ b/public/language/nl/topic.json @@ -27,7 +27,7 @@ "flag": "Markeren", "locked": "Gesloten", "pinned": "Pinned", - "moved": "Moved", + "moved": "Verplaatst", "bookmark_instructions": "Klik hier om terug te keren naar de laatst gelezen post in deze thread.", "flag_title": "Bericht aan beheerders melden", "flag_success": "Dit bericht is gerapporteerd aan de beheerder.", diff --git a/public/language/sl/category.json b/public/language/sl/category.json index f2c156394d..63495a5f90 100644 --- a/public/language/sl/category.json +++ b/public/language/sl/category.json @@ -1,6 +1,6 @@ { "category": "Kategorija", - "subcategories": "Podkategorija", + "subcategories": "Podkategorije", "new_topic_button": "Nova tema", "guest-login-post": "Za objavljanje moraš biti prijavljen", "no_topics": "V tej kategoriji ni tem.
    Boš odprl novo temo?", @@ -10,11 +10,11 @@ "share_this_category": "Deli to kategorijo", "watch": "Spremljaj", "ignore": "Ne spremljaj", - "watching": "Watching", - "ignoring": "Ignoring", - "watching.description": "Show topics in unread", - "ignoring.description": "Do not show topics in unread", + "watching": "Spremljanje", + "ignoring": "Prezri", + "watching.description": "Pokaži teme v neprebrano", + "ignoring.description": "Ne pokaži teme v neprebrano", "watch.message": "Trenutno spremljaš nove objave v tej kategoriji", "ignore.message": "Ne spremljaš novih objav v tej kategoriji", - "watched-categories": "Watched categories" + "watched-categories": "Spremljane kategorije" } \ No newline at end of file diff --git a/public/language/sl/email.json b/public/language/sl/email.json index b214e979b6..dcc9b48946 100644 --- a/public/language/sl/email.json +++ b/public/language/sl/email.json @@ -1,36 +1,36 @@ { - "password-reset-requested": "Zahtevana ponastavitev gesla - %1!", + "password-reset-requested": "Zahtevana je ponastavitev gesla - %1!", "welcome-to": "Pozdravljeni na %1", "invite": "Povabilo od %1", "greeting_no_name": "Živjo", "greeting_with_name": "Živjo %1", "welcome.text1": "Hvala, ker ste se registrirali na %1!", - "welcome.text2": "Za popolno aktivacijo vašega računa morate potrditi elektronski naslov s katerim ste se registrirali.", - "welcome.text3": "Administrator je odobril prošnjo za registracijo. Sedaj se lahko registrirate z vašim uporabniškim imenom in geslom.", - "welcome.cta": "Kliknite za potrditev vašega elektronskega naslova", + "welcome.text2": "Za popolno aktivacijo vašega računa morate potrditi e-poštni naslov s katerim ste se registrirali.", + "welcome.text3": "Srbnik je odobril prošnjo za registracijo. Sedaj se lahko registrirate z vašim uporabniškim imenom in geslom.", + "welcome.cta": "Kliknite za potrditev vašega e-poštnega naslova", "invitation.text1": "%1 te je povabil, da se pridružiš %2", - "invitation.ctr": "Klikni tu za kreiranje vašega računa.", + "invitation.ctr": "Klikni tu in ustvari svoj račun.", "reset.text1": "Dobili smo zahtevo za ponastavitev vašega gesla. Če niste zahtevali ponastavitve gesla, prosimo prezrite to sporočilo.", "reset.text2": "Za nadaljevanje ponastavitve gesla prosimo kliknite na sledečo povezavo:", "reset.cta": "Kliknite tu za ponastavitev gesla", "reset.notify.subject": "Geslo uspešno spremenjeno", "reset.notify.text1": "Obveščamo vas, da je bilo na %1 uspešno spremenjeno vaše geslo.", - "reset.notify.text2": "Če niste dali te zahteve, prosimo nemudoma kontaktirajte administratorja.", + "reset.notify.text2": "Če niste dali te zahteve, prosimo nemudoma obvestite skrbnika.", "digest.notifications": "Imate eno neprebrano obvestilo na %1:", "digest.latest_topics": "Zadnja tema na %1", "digest.cta": "Kliknite tu za obisk %1", - "digest.unsub.info": "Ta izvleček je bil poslan zaradi vaših nastavitev obvestil.", - "digest.no_topics": "V preteklosti ni bilo aktivnih tem na %1", - "digest.day": "day", - "digest.week": "week", - "digest.month": "month", - "digest.subject": "Digest for %1", - "notif.chat.subject": "Novo sporočilo prejeto na %1", + "digest.unsub.info": "Ta izvleček vam je bil poslan zaradi vaših nastavitev naročnine.", + "digest.no_topics": "%1, ki je pretekel ni imel aktivnih tem.", + "digest.day": "dan", + "digest.week": "teden", + "digest.month": "mesec", + "digest.subject": "Povzetek za %1", + "notif.chat.subject": "Novo sporočilo klepeta prejeto na %1", "notif.chat.cta": "Kliknite tu za nadaljevanje pogovora", - "notif.chat.unsub.info": "Obvestilu o pogovoru je bilo poslano zaradi vaših nastavitev obvestil.", - "notif.post.cta": "Kliknite tu za celotno temo.", - "notif.post.unsub.info": "Obvestilo o odgovoru je bilo poslano zaradi vaših nastavitev obvestil.", - "test.text1": "To je testno elektronsko sporočilo za preverjanje prejemnika, če je pravilno nastavil NodeBB.", + "notif.chat.unsub.info": "Obvestilo o klepetu vam je bilo poslano zaradi vaših nastavitev naročnine.", + "notif.post.cta": "Kliknite tu, če želite prebrati celotno temo.", + "notif.post.unsub.info": "Obvestilo o objavi je bilo poslano zaradi vaših nastavitev naročnine.", + "test.text1": "To je testno elektronsko sporočilo, služi preverjanju pravilnosti nastavite podsistema za pošiljanje NodeBB poštnih sporočil.", "unsub.cta": "Kliknite tu za spremembo nastavitev.", "closing": "Hvala!" } \ No newline at end of file diff --git a/public/language/sl/error.json b/public/language/sl/error.json index be36f337e3..aa23d38025 100644 --- a/public/language/sl/error.json +++ b/public/language/sl/error.json @@ -26,8 +26,8 @@ "sendmail-not-found": "The sendmail executable could not be found, please ensure it is installed and executable by the user running NodeBB.", "username-too-short": "Uporabniško ime je prekratko", "username-too-long": "Uporabniško ime je predolgo", - "password-too-long": "Password too long", - "user-banned": "Uporabnik je blokiran", + "password-too-long": "Geslo je predolgo", + "user-banned": "Uporabnik je izločen", "user-too-new": "Oprostite, počakajte %1 sekund pred vašo prvo objavo", "blacklisted-ip": "Sorry, your IP address has been banned from this community. If you feel this is in error, please contact an administrator.", "ban-expiry-missing": "Please provide an end date for this ban", @@ -69,15 +69,15 @@ "guest-upload-disabled": "Guest uploading has been disabled", "already-favourited": "You have already bookmarked this post", "already-unfavourited": "You have already unbookmarked this post", - "cant-ban-other-admins": "Ne morete blokirati drugih administratorjev!", - "cant-remove-last-admin": "Ste edini administrator. Dodajte novega administratorja preden boste odstranili sebe.", + "cant-ban-other-admins": "Ne morete izločiti drugih skrbnikov!", + "cant-remove-last-admin": "Ste edini skrbnik. Preden se boste odstranili, dodajte novega skrbnika.", "cant-delete-admin": "Remove administrator privileges from this account before attempting to delete it.", "invalid-image-type": "Nedovoljen format slike. Dovoljeni formati so: %1", - "invalid-image-extension": "Nedovoljena končnica slike", - "invalid-file-type": "Nedovoljen format datoteke. Dovoljeni formati so: %1", + "invalid-image-extension": "Nedovoljena pripona slike", + "invalid-file-type": "Nedovoljena vrsta datoteke. Dovoljene vrste so: %1", "group-name-too-short": "Ime skupine je prekratko", - "group-name-too-long": "Group name too long", - "group-already-exists": "Skupina še obstaja", + "group-name-too-long": "Ime skupine je predolgo", + "group-already-exists": "Skupina že obstaja", "group-name-change-not-allowed": "Sprememba imena skupine ni dovoljena", "group-already-member": "Already part of this group", "group-not-member": "Not a member of this group", @@ -85,26 +85,26 @@ "group-already-invited": "Ta uporabnik je že bil povabljen", "group-already-requested": "Vaša prošnja za članstvo je že bila sprejeta.", "post-already-deleted": "Ta objava je že bila izbrisana", - "post-already-restored": "Ta objava je že bila razveljavljena", + "post-already-restored": "Ta objava je že bila obnovljena", "topic-already-deleted": "Ta tema je že bila izbrisana", - "topic-already-restored": "Ta tema je že bila razveljavljena", + "topic-already-restored": "Ta tema je že bila obnovljena", "cant-purge-main-post": "Ne morete odstraniti prve objave, prosimo izbrišite temo.", "topic-thumbnails-are-disabled": "Sličice teme so onemogočene.", "invalid-file": "Nedovoljena datoteka", - "uploads-are-disabled": "Nalaganje je onemogočeno", + "uploads-are-disabled": "Prenosi so onemogočeni", "signature-too-long": "Vaš podpis ne sme biti daljši od %1 znak(ov).", "about-me-too-long": "Rubrika \"O meni\" ne sme biti daljša od %1 znak(ov).", "cant-chat-with-yourself": "Ne morete klepetati s seboj!", - "chat-restricted": "Uporabnik je omejil klepetanje. Za možnost klepetanja vas mora uporabnik slediti", - "chat-disabled": "Chat system disabled", + "chat-restricted": "Uporabnik je omejil klepetanje. Za možnost klepetanja vas mora uporabnik spremljati", + "chat-disabled": "Klepet je onemogočen", "too-many-messages": "Poslali ste veliko število sporočil, prosimo počakajte nekaj časa.", - "invalid-chat-message": "Invalid chat message", - "chat-message-too-long": "Chat message is too long", + "invalid-chat-message": "Neveljavno sporočilo klepeta", + "chat-message-too-long": "Sporočilo klepeta je predolgo", "cant-edit-chat-message": "You are not allowed to edit this message", "cant-remove-last-user": "You can't remove the last user", "cant-delete-chat-message": "You are not allowed to delete this message", "already-voting-for-this-post": "You have already voted for this post.", - "reputation-system-disabled": "Možnost ugleda je onemogočena.", + "reputation-system-disabled": "Sistem za ugled je onemogočen.", "downvoting-disabled": "Negativno glasovanje je onemogočeno", "not-enough-reputation-to-downvote": "Nimate dovolj ugleda za negativno glasovanje", "not-enough-reputation-to-flag": "Nimate dovolj ugleda za prijavo te objave", @@ -112,7 +112,7 @@ "reload-failed": "NodeBB je zaznal težavo pri osveževanju: ", "registration-error": "Napaka pri registraciji", "parse-error": "Nekaj je šlo narobe pri pridobivanju odgovora s strežnika", - "wrong-login-type-email": "Uporabite svoj e-mail naslov za prijavo", + "wrong-login-type-email": "Uporabite svoj e-poštni naslov za prijavo", "wrong-login-type-username": "Uporabite svoje uporabniško ime za prijavo", "invite-maximum-met": "You have invited the maximum amount of people (%1 out of %2).", "no-session-found": "No login session found!", diff --git a/public/language/sl/global.json b/public/language/sl/global.json index f26add34d6..5dd5474601 100644 --- a/public/language/sl/global.json +++ b/public/language/sl/global.json @@ -52,8 +52,8 @@ "best": "Best", "upvoters": "Upvoters", "upvoted": "Upvoted", - "downvoters": "Downvoters", - "downvoted": "Downvoted", + "downvoters": "Negativnih glasovalcev", + "downvoted": "Negativno glasovano", "views": "Ogledi", "reputation": "Ugled", "read_more": "preberi več", diff --git a/public/language/sl/pages.json b/public/language/sl/pages.json index 27eebd626a..e89f935421 100644 --- a/public/language/sl/pages.json +++ b/public/language/sl/pages.json @@ -39,7 +39,7 @@ "account/settings": "Uporabniške nastavitve", "account/watched": "Teme, ki jih spremlja uporabnik %1", "account/upvoted": "Posts upvoted by %1", - "account/downvoted": "Posts downvoted by %1", + "account/downvoted": "Negativno glasovane objave od %1", "account/best": "Best posts made by %1", "confirm": "Email Confirmed", "maintenance.text": "%1 je trenutno v prenovi. Prosimo pridite nazaj kasneje.", diff --git a/public/language/sl/tags.json b/public/language/sl/tags.json index 4fbbab14d8..954005559f 100644 --- a/public/language/sl/tags.json +++ b/public/language/sl/tags.json @@ -3,5 +3,5 @@ "tags": "Oznake", "enter_tags_here": "Tu vpišite oznake, med %1 in %2 znaki.", "enter_tags_here_short": "Vpišite oznake...", - "no_tags": "Ni še oznak." + "no_tags": "Nobene oznake še ni." } \ No newline at end of file diff --git a/public/language/sl/topic.json b/public/language/sl/topic.json index 225d18110b..cc00affa99 100644 --- a/public/language/sl/topic.json +++ b/public/language/sl/topic.json @@ -13,7 +13,7 @@ "notify_me": "Bodi obveščen o novih odgovorih na to temo", "quote": "Citiraj", "reply": "Odgovori", - "reply-as-topic": "Reply as topic", + "reply-as-topic": "Odgovori z temo", "guest-login-reply": "Prijavi se za odgovor", "edit": "Uredi", "delete": "Izbriši", @@ -26,44 +26,44 @@ "tools": "Orodja", "flag": "Prijavi", "locked": "Zaklenjeno", - "pinned": "Pinned", - "moved": "Moved", - "bookmark_instructions": "Click here to return to the last read post in this thread.", - "flag_title": "Prijavi to objavo v pregled administratorju", + "pinned": "Pripeto", + "moved": "Premaknjeno", + "bookmark_instructions": "Klikni tukaj za vrnitev na zadnje prebrano objavo v tej niti", + "flag_title": "Označi to objavo za vodenje", "flag_success": "Ta objava je bila prijavljena v pregled administratorju.", - "deleted_message": "Ta tema je bila izbrisana. Le uporabniki s pravicami teme jo lahko vidijo.", - "following_topic.message": "Sedaj boste dobili obvestila, ko bo nekdo objavil v to temo.", + "deleted_message": "Ta tema je bila izbrisana. Le uporabniki s pravicami upravljanja tem jo lahko vidijo.", + "following_topic.message": "Ob objavi v to temo, boste od sedaj dobivali obvestila. ", "not_following_topic.message": "You will see this topic in the unread topics list, but you will not receive notifications when somebody posts to this topic.", "ignoring_topic.message": "You will no longer see this topic in the unread topics list. You will be notified when you are mentioned or your post is up voted.", "login_to_subscribe": "Prosimo prijavite ali registrirajte se za naročanje o tej temi.", "markAsUnreadForAll.success": "Tema označena kot neprebrana za vse.", - "mark_unread": "Mark unread", - "mark_unread.success": "Topic marked as unread.", + "mark_unread": "Označi kot neprebrano", + "mark_unread.success": "Tema označena kot neprebrana.", "watch": "Spremljaj", "unwatch": "Ne spremljaj", "watch.title": "Bodi obveščen o novih odgovorih v tej temi", "unwatch.title": "Prenehaj spremljati to temo", "share_this_post": "Deli to objavo", - "watching": "Watching", - "not-watching": "Not Watching", - "ignoring": "Ignoring", + "watching": "Spremljano", + "not-watching": "Ni spremljano", + "ignoring": "Prezri", "watching.description": "Notify me of new replies.
    Show topic in unread.", "not-watching.description": "Do not notify me of new replies.
    Show topic in unread if category is not ignored.", "ignoring.description": "Do not notify me of new replies.
    Do not show topic in unread.", "thread_tools.title": "Orodja teme", "thread_tools.markAsUnreadForAll": "Označi kot neprebrano", - "thread_tools.pin": "Prilepi temo", - "thread_tools.unpin": "Odlepi temo", + "thread_tools.pin": "Pripni temo", + "thread_tools.unpin": "Odpni temo", "thread_tools.lock": "Zakleni temo", "thread_tools.unlock": "Odkleni temo", - "thread_tools.move": "Prestavi temo", - "thread_tools.move_all": "Prestavi vse", + "thread_tools.move": "Premakni temo", + "thread_tools.move_all": "Premakni vse", "thread_tools.fork": "Razcepi temo", "thread_tools.delete": "Izbriši temo", - "thread_tools.delete-posts": "Delete Posts", + "thread_tools.delete-posts": "Izbriši objave", "thread_tools.delete_confirm": "Ste prepričani, da želite izbrisati to temo?", - "thread_tools.restore": "Razveljavi temo", - "thread_tools.restore_confirm": "Ste prepričani, da želite razveljaviti to temo?", + "thread_tools.restore": "Obnovi temo", + "thread_tools.restore_confirm": "Ste prepričani, da želite obnoviti to temo?", "thread_tools.purge": "Očisti temo", "thread_tools.purge_confirm": "Ste prepričani, da želite očistiti to temo?", "topic_move_success": "Ta tema je bila uspešno prestavljena v %1", @@ -74,9 +74,9 @@ "disabled_categories_note": "Onemogočene kategorije so obarvane sivo", "confirm_move": "Premakni", "confirm_fork": "Razcepi", - "favourite": "Bookmark", - "favourites": "Bookmarks", - "favourites.has_no_favourites": "You haven't bookmarked any posts yet.", + "favourite": "Zaznamek", + "favourites": "Zaznamki", + "favourites.has_no_favourites": "Zaznamovali še niste nobenih objav.", "loading_more_posts": "Nalagam več objav", "move_topic": "Premakni temo", "move_topics": "Premakni teme", diff --git a/public/language/sl/uploads.json b/public/language/sl/uploads.json index 1622cb5693..85ee20d0c2 100644 --- a/public/language/sl/uploads.json +++ b/public/language/sl/uploads.json @@ -1,6 +1,6 @@ { - "uploading-file": "Uploading the file...", - "select-file-to-upload": "Select a file to upload!", - "upload-success": "File uploaded successfully!", - "maximum-file-size": "Maximum %1 kb" + "uploading-file": "Prenašanje datoteke ...", + "select-file-to-upload": "Izberete datoteko, ki jo želite prenesti!", + "upload-success": "Datoteka je bila uspešno prenesena!", + "maximum-file-size": "Največ %1 kb " } \ No newline at end of file diff --git a/public/language/sl/user.json b/public/language/sl/user.json index 57a2b00c47..330d37b7ee 100644 --- a/public/language/sl/user.json +++ b/public/language/sl/user.json @@ -1,19 +1,19 @@ { - "banned": "Blokirani", + "banned": "Izločen", "offline": "Odjavljeni", "username": "Uporabniško ime", "joindate": "Datum pridružitve", "postcount": "Število objav", "email": "E-pošta", "confirm_email": "Potrdi e-poštni naslov", - "account_info": "Account Info", - "ban_account": "Blokiraj račun", - "ban_account_confirm": "Ali želiš blokirati uporabnika?", - "unban_account": "Odblokiraj račun", + "account_info": "Podatki računa", + "ban_account": "Izločen račun", + "ban_account_confirm": "Ali želiš izločiti uporabnika?", + "unban_account": "Ponovno vključi račun", "delete_account": "Izbriši račun", "delete_account_confirm": "Ali želiš izbrisati račun?
    S potrditvijo bodo izbrisani vsi podatki, ki jih ne bo več možno obnoviti.

    Vpiši svoje uporabniško ime za dokončanje procesa.", "delete_this_account_confirm": "Ali želiš izbrisati račun?
    S potrditvijo bodo izbrisani vsi podatki, ki jih ne bo več možno obnoviti.

    ", - "account-deleted": "Account deleted", + "account-deleted": "Račun je izbrisan", "fullname": "Ime in priimek", "website": "Spletna stran", "location": "Lokacija", @@ -23,25 +23,25 @@ "profile": "Profil", "profile_views": "Ogledi", "reputation": "Naziv", - "favourites": "Bookmarks", - "watched": "Zgodovina ogledov", - "followers": "Sledilci", - "following": "Sledim", + "favourites": "Zaznamki", + "watched": "Spremljano", + "followers": "Spremljevalci", + "following": "Spremljano", "aboutme": "O meni", "signature": "Podpis", "birthday": "Rojstni datum", "chat": "Klepet", - "chat_with": "Chat with %1", + "chat_with": "Klepet z %1", "follow": "Spremljaj", "unfollow": "Ne spremljaj", "more": "Več", - "profile_update_success": "Prosil je bil uspešno posodobljen.", + "profile_update_success": "Profil je bil uspešno posodobljen.", "change_picture": "Spremeni sliko", - "change_username": "Change Username", - "change_email": "Change Email", + "change_username": "Spremeni uporabniško ime", + "change_email": "Spremeni e-poštni naslov", "edit": "Uredi", - "edit-profile": "Edit Profile", - "default_picture": "Default Icon", + "edit-profile": "Uredi profil", + "default_picture": "Privzeta ikona", "uploaded_picture": "Naloži fotografijo", "upload_new_picture": "Naloži novo fotografijo", "upload_new_picture_from_url": "Naloži novo fotografijo s spletnega naslova", @@ -56,12 +56,12 @@ "confirm_password": "Potrdi geslo", "password": "Geslo", "username_taken_workaround": "Predlagano uporabniško ime je že zasedeno, zato predlagamo %1", - "password_same_as_username": "Your password is the same as your username, please select another password.", - "password_same_as_email": "Your password is the same as your email, please select another password.", + "password_same_as_username": "Vaše geslo je enako kot vaše uporabniško ime, prosim izberite drugačno geslo.", + "password_same_as_email": "Vaše geslo je enako kot vaše e-poštni naslov, prosim izberite drugačno geslo.", "upload_picture": "Naloži fotografijo", "upload_a_picture": "Naloži fotografijo", - "remove_uploaded_picture": "Remove Uploaded Picture", - "upload_cover_picture": "Upload cover picture", + "remove_uploaded_picture": "Odstrani preneseno sliko ", + "upload_cover_picture": "Prenesi fotografijo naslovnice", "settings": "Nastavitve.", "show_email": "Pokaži moj e-poštni naslov.", "show_fullname": "Pokaži moj ime in priimek.", @@ -80,9 +80,9 @@ "has_no_posts": "Uporabnik še ni ustvaril nobene objave.", "has_no_topics": "Uporabnik še ni odprl nobene teme.", "has_no_watched_topics": "Uporabnik še ne spremlja nobene teme.", - "has_no_upvoted_posts": "This user hasn't upvoted any posts yet.", - "has_no_downvoted_posts": "This user hasn't downvoted any posts yet.", - "has_no_voted_posts": "This user has no voted posts", + "has_no_upvoted_posts": "Uporabnik še ni pritrdil nobeni objavi.", + "has_no_downvoted_posts": "Uporabnik še ni ne pritrdil nobeni objavi.", + "has_no_voted_posts": "Uporabnik še nima nobene pritrditve objavam", "email_hidden": "Skrit e-poštni naslov", "hidden": "skrit", "paginate_description": "Uporabi oštevilčenje strani namesto neskončnega drsenja", @@ -93,14 +93,14 @@ "open_links_in_new_tab": "Zunanje povezave odpri v novem zavihku", "enable_topic_searching": "Omogoči iskanje znotraj teme", "topic_search_help": "Če omogočite, bo iskanje prepisalo brskalnikove prevzete nastavitve in vam omogočilo iskanje skozi celotno temo.", - "delay_image_loading": "Delay Image Loading", + "delay_image_loading": "Zakasnitev pri nalaganju slike", "image_load_delay_help": "If enabled, images in topics will not load until they are scrolled into view", "scroll_to_my_post": "After posting a reply, show the new post", - "follow_topics_you_reply_to": "Watch topics that you reply to", - "follow_topics_you_create": "Watch topics you create", + "follow_topics_you_reply_to": "Spremljanj teme, na katere si odgovoril", + "follow_topics_you_create": "Spremljanj teme, ki si jih ustvaril", "grouptitle": "Group Title", "no-group-title": "Skupina nima imena", - "select-skin": "Izberi obliko", + "select-skin": "Izberi preobleko", "select-homepage": "Select a Homepage", "homepage": "Homepage", "homepage_description": "Select a page to use as the forum homepage or 'None' to use the default homepage.", From f62da5c4e9b0fc66ea61361d28dd70e4bf818d63 Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Tue, 9 Aug 2016 09:50:49 -0500 Subject: [PATCH 05/63] see NodeBB/NodeBB#4909 --- public/src/client/topic/posts.js | 2 +- src/categories/create.js | 2 +- src/privileges.js | 8 +++---- src/privileges/categories.js | 16 +++++++------- src/privileges/posts.js | 10 ++++----- src/privileges/topics.js | 8 +++---- src/topics/posts.js | 4 ++-- src/upgrade.js | 22 +++++++++---------- .../admin/partials/categories/groups.tpl | 4 ++-- src/views/admin/partials/categories/users.tpl | 4 ++-- 10 files changed, 40 insertions(+), 40 deletions(-) diff --git a/public/src/client/topic/posts.js b/public/src/client/topic/posts.js index d9011d530d..33be04f993 100644 --- a/public/src/client/topic/posts.js +++ b/public/src/client/topic/posts.js @@ -28,7 +28,7 @@ define('forum/topic/posts', [ data.posts.forEach(function(post) { post.selfPost = !!app.user.uid && parseInt(post.uid, 10) === parseInt(app.user.uid, 10); post.display_edit_tools = (ajaxify.data.privileges.editOwnPosts && post.selfPost) || ajaxify.data.privileges.isAdminOrMod; - post.display_delete_tools = (ajaxify.data.privileges.editOwnPosts && post.selfPost) || ajaxify.data.privileges.isAdminOrMod; + post.display_delete_tools = (ajaxify.data.privileges.deleteOwnPosts && post.selfPost) || ajaxify.data.privileges.isAdminOrMod; post.display_moderator_tools = post.display_edit_tools || post.display_delete_tools; post.display_move_tools = ajaxify.data.privileges.isAdminOrMod; post.display_post_menu = ajaxify.data.privileges.isAdminOrMod || post.selfPost || ((app.user.uid || ajaxify.data.postSharing.length) && !post.deleted); diff --git a/src/categories/create.js b/src/categories/create.js index a42c260155..4f00da8149 100644 --- a/src/categories/create.js +++ b/src/categories/create.js @@ -48,7 +48,7 @@ module.exports = function(Categories) { function(data, next) { category = data.category; - var defaultPrivileges = ['find', 'read', 'topics:read', 'topics:create', 'topics:reply', 'edit', 'delete', 'upload:post:image']; + var defaultPrivileges = ['find', 'read', 'topics:read', 'topics:create', 'topics:reply', 'posts:edit', 'posts:delete', 'upload:post:image']; async.series([ async.apply(db.setObject, 'category:' + category.cid, category), diff --git a/src/privileges.js b/src/privileges.js index cc1e4d48ed..34b6e6fb69 100644 --- a/src/privileges.js +++ b/src/privileges.js @@ -8,8 +8,8 @@ privileges.userPrivilegeList = [ 'topics:read', 'topics:create', 'topics:reply', - 'edit', - 'delete', + 'posts:edit', + 'posts:delete', 'topics:delete', 'upload:post:image', 'upload:post:file', @@ -23,8 +23,8 @@ privileges.groupPrivilegeList = [ 'groups:topics:read', 'groups:topics:create', 'groups:topics:reply', - 'groups:edit', - 'groups:delete', + 'groups:posts:edit', + 'groups:posts:delete', 'groups:topics:delete', 'groups:upload:post:image', 'groups:upload:post:file', diff --git a/src/privileges/categories.js b/src/privileges/categories.js index 96eaba84c4..0baf08af91 100644 --- a/src/privileges/categories.js +++ b/src/privileges/categories.js @@ -365,11 +365,11 @@ module.exports = function(privileges) { 'topics:reply': function(next) { groups.isMember(uid, 'cid:' + cid + ':privileges:topics:reply', next); }, - 'edit': function(next) { - groups.isMember(uid, 'cid:' + cid + ':privileges:edit', next); + 'posts:edit': function(next) { + groups.isMember(uid, 'cid:' + cid + ':privileges:posts:edit', next); }, - 'delete': function(next) { - groups.isMember(uid, 'cid:' + cid + ':privileges:delete', next); + 'posts:delete': function(next) { + groups.isMember(uid, 'cid:' + cid + ':privileges:posts:delete', next); }, 'topics:delete': function(next) { groups.isMember(uid, 'cid:' + cid + ':privileges:topics:delete', next); @@ -392,11 +392,11 @@ module.exports = function(privileges) { 'groups:topics:reply': function(next) { groups.isMember(groupName, 'cid:' + cid + ':privileges:groups:topics:reply', next); }, - 'groups:edit': function(next) { - groups.isMember(groupName, 'cid:' + cid + ':privileges:groups:edit', next); + 'groups:posts:edit': function(next) { + groups.isMember(groupName, 'cid:' + cid + ':privileges:groups:posts:edit', next); }, - 'groups:delete': function(next) { - groups.isMember(groupName, 'cid:' + cid + ':privileges:groups:delete', next); + 'groups:posts:delete': function(next) { + groups.isMember(groupName, 'cid:' + cid + ':privileges:groups:posts:delete', next); }, 'groups:topics:delete': function(next) { groups.isMember(groupName, 'cid:' + cid + ':privileges:groups:topics:delete', next); diff --git a/src/privileges/posts.js b/src/privileges/posts.js index c946e8c744..fe43a631c6 100644 --- a/src/privileges/posts.js +++ b/src/privileges/posts.js @@ -30,7 +30,7 @@ module.exports = function(privileges) { isOwner: async.apply(posts.isOwner, pids, uid), 'topics:read': async.apply(helpers.isUserAllowedTo, 'topics:read', uid, cids), read: async.apply(helpers.isUserAllowedTo, 'read', uid, cids), - edit: async.apply(helpers.isUserAllowedTo, 'edit', uid, cids), + 'posts:edit': async.apply(helpers.isUserAllowedTo, 'posts:edit', uid, cids), }, next); } ], function(err, results) { @@ -42,7 +42,7 @@ module.exports = function(privileges) { for (var i=0; iAccess Topics
  • Create Topics
  • Reply to Topics
  • -
  • Edit Posts
  • -
  • Delete Posts
  • +
  • Edit Posts
  • +
  • Delete Posts
  • Delete Topics
  • diff --git a/src/views/admin/partials/categories/users.tpl b/src/views/admin/partials/categories/users.tpl index c97d452d5d..772053d5b0 100644 --- a/src/views/admin/partials/categories/users.tpl +++ b/src/views/admin/partials/categories/users.tpl @@ -10,8 +10,8 @@
  • Access Topics
  • Create Topics
  • Reply to Topics
  • -
  • Edit Posts
  • -
  • Delete Posts
  • +
  • Edit Posts
  • +
  • Delete Posts
  • Delete Topics
  • Moderator
  • From c44c689ebf4ce3c21aff722ebf980495598c5d71 Mon Sep 17 00:00:00 2001 From: Anil Mandepudi Date: Tue, 9 Aug 2016 07:54:58 -0700 Subject: [PATCH 06/63] fixes #4921 (#4922) --- public/src/admin/advanced/errors.js | 66 +++++++++++++++++++-------- public/src/admin/general/dashboard.js | 3 +- 2 files changed, 48 insertions(+), 21 deletions(-) diff --git a/public/src/admin/advanced/errors.js b/public/src/admin/advanced/errors.js index 2e72bcceb5..52d6427240 100644 --- a/public/src/admin/advanced/errors.js +++ b/public/src/admin/advanced/errors.js @@ -29,7 +29,7 @@ define('admin/advanced/errors', ['Chart'], function(Chart) { dailyLabels = dailyLabels.slice(-7); if (utils.isMobile()) { - Chart.defaults.global.showTooltips = false; + Chart.defaults.global.tooltips.enabled = false; } var data = { @@ -38,12 +38,12 @@ define('admin/advanced/errors', ['Chart'], function(Chart) { datasets: [ { label: "", - fillColor: "rgba(186,139,175,0.2)", - strokeColor: "rgba(186,139,175,1)", - pointColor: "rgba(186,139,175,1)", - pointStrokeColor: "#fff", - pointHighlightFill: "#fff", - pointHighlightStroke: "rgba(186,139,175,1)", + backgroundColor: "rgba(186,139,175,0.2)", + borderColor: "rgba(186,139,175,1)", + pointBackgroundColor: "rgba(186,139,175,1)", + pointHoverBackgroundColor: "#fff", + pointBorderColor: "#fff", + pointHoverBorderColor: "rgba(186,139,175,1)", data: ajaxify.data.analytics['not-found'] } ] @@ -53,12 +53,12 @@ define('admin/advanced/errors', ['Chart'], function(Chart) { datasets: [ { label: "", - fillColor: "rgba(151,187,205,0.2)", - strokeColor: "rgba(151,187,205,1)", - pointColor: "rgba(151,187,205,1)", - pointStrokeColor: "#fff", - pointHighlightFill: "#fff", - pointHighlightStroke: "rgba(151,187,205,1)", + backgroundColor: "rgba(151,187,205,0.2)", + borderColor: "rgba(151,187,205,1)", + pointBackgroundColor: "rgba(151,187,205,1)", + pointHoverBackgroundColor: "#fff", + pointBorderColor: "#fff", + pointHoverBorderColor: "rgba(151,187,205,1)", data: ajaxify.data.analytics['toobusy'] } ] @@ -67,13 +67,41 @@ define('admin/advanced/errors', ['Chart'], function(Chart) { notFoundCanvas.width = $(notFoundCanvas).parent().width(); tooBusyCanvas.width = $(tooBusyCanvas).parent().width(); - new Chart(notFoundCanvas.getContext('2d')).Line(data['not-found'], { - responsive: true, - animation: false + + new Chart(notFoundCanvas.getContext('2d'), { + type: 'line', + data: data['not-found'], + options: { + responsive: true, + legend: { + display: false + }, + scales: { + yAxes: [{ + ticks: { + beginAtZero: true + } + }] + } + } }); - new Chart(tooBusyCanvas.getContext('2d')).Line(data['toobusy'], { - responsive: true, - animation: false + + new Chart(tooBusyCanvas.getContext('2d'), { + type: 'line', + data: data['toobusy'], + options: { + responsive: true, + legend: { + display: false + }, + scales: { + yAxes: [{ + ticks: { + beginAtZero: true + } + }] + } + } }); }; diff --git a/public/src/admin/general/dashboard.js b/public/src/admin/general/dashboard.js index 1071c76b0d..1224d2ace2 100644 --- a/public/src/admin/general/dashboard.js +++ b/public/src/admin/general/dashboard.js @@ -165,8 +165,7 @@ define('admin/general/dashboard', ['semver', 'Chart'], function(semver, Chart) { trafficLabels = utils.getHoursArray(); if (isMobile) { - Chart.defaults.global.showTooltips = false; - Chart.defaults.global.animation = false; + Chart.defaults.global.tooltips.enabled = false; } var data = { From 19b4679c0e79e43e90ada34ff57864212a69fd3a Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Tue, 9 Aug 2016 12:32:50 -0400 Subject: [PATCH 07/63] properly handling flattened dependencies in plugin scripts --- src/plugins/load.js | 42 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/src/plugins/load.js b/src/plugins/load.js index a70fce41ab..70aea70ccd 100644 --- a/src/plugins/load.js +++ b/src/plugins/load.js @@ -153,22 +153,22 @@ module.exports = function(Plugins) { } Plugins.clientScripts = Plugins.clientScripts.concat(pluginData.scripts.map(function(file) { - return path.join(__dirname, '../../node_modules/', pluginData.id, file); - })); + return resolveModulePath(path.join(__dirname, '../../node_modules/', pluginData.id, file), file); + })).filter(Boolean); } if (Array.isArray(pluginData.acpScripts)) { if (global.env === 'development') { - winston.verbose('[plugins] Found ' + pluginData.acpScripts.length + ' js file(s) for plugin ' + pluginData.id); + winston.verbose('[plugins] Found ' + pluginData.acpScripts.length + ' ACP js file(s) for plugin ' + pluginData.id); } Plugins.acpScripts = Plugins.acpScripts.concat(pluginData.acpScripts.map(function(file) { - return path.join(__dirname, '../../node_modules/', pluginData.id, file); - })); + return resolveModulePath(path.join(__dirname, '../../node_modules/', pluginData.id, file), file); + })).filter(Boolean); } callback(); - }; + } function mapClientModules(pluginData, callback) { if (!pluginData.hasOwnProperty('modules')) { @@ -201,14 +201,16 @@ module.exports = function(Plugins) { } for (var name in pluginData.modules) { - modules[name] = path.join('./node_modules/', pluginData.id, pluginData.modules[name]); + if (pluginData.modules.hasOwnProperty(name)) { + modules[name] = path.join('./node_modules/', pluginData.id, pluginData.modules[name]); + } } meta.js.scripts.modules = _.extend(meta.js.scripts.modules, modules); } callback(); - }; + } function loadLanguages(pluginData, callback) { if (typeof pluginData.languages !== 'string') { @@ -265,6 +267,30 @@ module.exports = function(Plugins) { }); } + function resolveModulePath(fullPath, relPath) { + /** + * With npm@3, dependencies can become flattened, and appear at the root level. + * This method resolves these differences if it can. + */ + var atRootLevel = fullPath.match(/node_modules/g).length === 1; + + try { + fs.statSync(fullPath); + winston.verbose('[plugins/load] File found: ' + fullPath); + return fullPath; + } catch (e) { + // File not visible to the calling process, ascend to root level if possible and try again + if (!atRootLevel && relPath) { + winston.verbose('[plugins/load] File not found: ' + fullPath + ' (Ascending)'); + return resolveModulePath(path.join(__dirname, '../..', relPath)); + } else { + // Already at root level, file was simply not found + winston.warn('[plugins/load] File not found: ' + fullPath + ' (Ignoring)'); + return null; + } + } + } + Plugins.loadPluginInfo = function(pluginPath, callback) { async.parallel({ package: function(next) { From fd8f5f9415d17c646dfa7d0806050f4f38785c93 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Tue, 9 Aug 2016 12:56:42 -0400 Subject: [PATCH 08/63] closes #4918 --- src/socket.io/user.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/socket.io/user.js b/src/socket.io/user.js index c38bcc5bbf..44c17ea476 100644 --- a/src/socket.io/user.js +++ b/src/socket.io/user.js @@ -1,7 +1,7 @@ 'use strict'; var async = require('async'); - +var winston = require('winston'); var user = require('../user'); var topics = require('../topics'); @@ -91,7 +91,17 @@ SocketUser.reset.send = function(socket, email, callback) { return callback(new Error('[[error:invalid-data]]')); } - user.reset.send(email, callback); + user.reset.send(email, function(err) { + if (err && err.message !== '[[error:invalid-email]]') { + return callback(err); + } + if (err && err.message === '[[error:invalid-email]]') { + winston.verbose('[user/reset] Invalid email attempt: ' + email); + return setTimeout(callback, 2500); + } + + callback(); + }); }; SocketUser.reset.commit = function(socket, data, callback) { From 709be213e500840a28ff2af32e54109c1dfb38bc Mon Sep 17 00:00:00 2001 From: psychobunny Date: Tue, 9 Aug 2016 15:35:52 -0400 Subject: [PATCH 09/63] up persona --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8523785316..8ad58b9c8c 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "nodebb-plugin-spam-be-gone": "0.4.9", "nodebb-rewards-essentials": "0.0.9", "nodebb-theme-lavender": "3.0.13", - "nodebb-theme-persona": "4.1.19", + "nodebb-theme-persona": "4.1.20", "nodebb-theme-vanilla": "5.1.9", "nodebb-widget-essentials": "2.0.10", "nodemailer": "2.0.0", From 9814652d764f27bc4b37527d52707206e9cb1237 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Wed, 10 Aug 2016 00:16:55 -0400 Subject: [PATCH 10/63] updating package.json to reflect latest version of NodeBB, for master branch --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8ad58b9c8c..fde24ac2ec 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "nodebb", "license": "GPL-3.0", "description": "NodeBB Forum", - "version": "1.1.0", + "version": "1.1.2", "homepage": "http://www.nodebb.org", "repository": { "type": "git", From d469d77d5e9f930fed47ef55fa5c0237b4324122 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Wed, 10 Aug 2016 11:06:30 +0300 Subject: [PATCH 11/63] closes #4924 --- public/language/en_GB/topic.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/language/en_GB/topic.json b/public/language/en_GB/topic.json index 78769c64b5..f177725d56 100644 --- a/public/language/en_GB/topic.json +++ b/public/language/en_GB/topic.json @@ -61,7 +61,7 @@ "ignoring.description": "Do not notify me of new replies.
    Do not show topic in unread.", "thread_tools.title": "Topic Tools", - "thread_tools.markAsUnreadForAll": "Mark Unread", + "thread_tools.markAsUnreadForAll": "Mark unread for all", "thread_tools.pin": "Pin Topic", "thread_tools.unpin": "Unpin Topic", "thread_tools.lock": "Lock Topic", From f394056b7c72859843269129d98e02b8c520dcf2 Mon Sep 17 00:00:00 2001 From: NodeBB Misty Date: Wed, 10 Aug 2016 09:02:41 -0400 Subject: [PATCH 12/63] Latest translations and fallbacks --- 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@pirate/topic.json | 1 + public/language/en_US/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/login.json | 2 +- public/language/fr/topic.json | 5 +++-- public/language/gl/topic.json | 1 + public/language/he/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/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/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/vi/topic.json | 1 + public/language/zh_CN/topic.json | 1 + public/language/zh_TW/topic.json | 1 + 41 files changed, 43 insertions(+), 3 deletions(-) diff --git a/public/language/ar/topic.json b/public/language/ar/topic.json index 9810d07d64..6ffaaa75d7 100644 --- a/public/language/ar/topic.json +++ b/public/language/ar/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "هذا الموضوع سوف ينقل إلى فئة", "fork_topic_instruction": "إضغط على المشاركات التي تريد تفريعها", "fork_no_pids": "لم تختر أي مشاركة", + "fork_pid_count": "%1 post(s) selected", "fork_success": "تم إنشاء فرع للموضوع بنجاح! إضغط هنا لمعاينة الفرع.", "delete_posts_instruction": "Click the posts you want to delete/purge", "composer.title_placeholder": "أدخل عنوان موضوعك هنا...", diff --git a/public/language/bg/topic.json b/public/language/bg/topic.json index 46f4a70313..c7853b18af 100644 --- a/public/language/bg/topic.json +++ b/public/language/bg/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Тази тема ще бъде преместена в категорията", "fork_topic_instruction": "Натиснете публикациите, които искате да отделите", "fork_no_pids": "Няма избрани публикации!", + "fork_pid_count": "Избрани публикации: %1", "fork_success": "Темата е разделена успешно! Натиснете тук, за да преминете към отделената тема.", "delete_posts_instruction": "Натиснете публикациите, които искате да изтриете/изчистите", "composer.title_placeholder": "Въведете заглавието на темата си тук...", diff --git a/public/language/bn/topic.json b/public/language/bn/topic.json index 51e88fd6e3..030f48311c 100644 --- a/public/language/bn/topic.json +++ b/public/language/bn/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "এই টপিকটি ক্যাটাগরীতে সরানো হবে", "fork_topic_instruction": "যে পোষ্টটি ফর্ক করতে চান সেটি ক্লিক করুন", "fork_no_pids": "কোন পোষ্ট সিলেক্ট করা হয় নি", + "fork_pid_count": "%1 post(s) selected", "fork_success": "টপিক ফর্ক করা হয়েছে। ফর্ক করা টপিকে যেতে এখানে ক্লিক করুন", "delete_posts_instruction": "Click the posts you want to delete/purge", "composer.title_placeholder": "আপনার টপিকের শিরোনাম দিন", diff --git a/public/language/cs/topic.json b/public/language/cs/topic.json index b528de0a8c..cc513a5dc4 100644 --- a/public/language/cs/topic.json +++ b/public/language/cs/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Toto téma bude přesunuto do kategorie", "fork_topic_instruction": "Vyber příspěvky, které chceš oddělit", "fork_no_pids": "Žádné příspěvky nebyly vybrány!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Successfully forked topic! Click here to go to the forked topic.", "delete_posts_instruction": "Click the posts you want to delete/purge", "composer.title_placeholder": "Zadejte název tématu...", diff --git a/public/language/da/topic.json b/public/language/da/topic.json index 22ca530310..181a58ffb7 100644 --- a/public/language/da/topic.json +++ b/public/language/da/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Denne tråd vil blive flyttet til katagorien", "fork_topic_instruction": "Klik på indlæg du ønsker at fraskille", "fork_no_pids": "Ingen indlæg valgt", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Tråden blev fraskilt! Klik her for at gå til den fraskilte tråd.", "delete_posts_instruction": "Klik på de indlæg du vil slette/rense", "composer.title_placeholder": "Angiv din trådtittel her ...", diff --git a/public/language/de/topic.json b/public/language/de/topic.json index 7d4cd8fc97..816f417397 100644 --- a/public/language/de/topic.json +++ b/public/language/de/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Dieses Thema wird verschoben nach", "fork_topic_instruction": "Klicke auf die Beiträge, die aufgespaltet werden sollen", "fork_no_pids": "Keine Beiträge ausgewählt!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Thema erfolgreich aufgespalten! Klicke hier, um zum aufgespalteten Thema zu gelangen.", "delete_posts_instruction": "Wähle die zu löschenden Beiträge aus", "composer.title_placeholder": "Hier den Titel des Themas eingeben...", diff --git a/public/language/el/topic.json b/public/language/el/topic.json index 7625226e7d..4cb37383e7 100644 --- a/public/language/el/topic.json +++ b/public/language/el/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Το θέμα θα μετακινηθεί στην κατηγορία", "fork_topic_instruction": "Κάνε κλικ στις δημοσιεύσεις που θέλεις να διαχωρίσεις", "fork_no_pids": "Δεν έχουν επιλεχθεί δημοσιεύσεις!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Successfully forked topic! Click here to go to the forked topic.", "delete_posts_instruction": "Click the posts you want to delete/purge", "composer.title_placeholder": "Εισαγωγή του τίτλου του θέματος εδώ...", diff --git a/public/language/en@pirate/topic.json b/public/language/en@pirate/topic.json index edcc8a8435..238f75eb0e 100644 --- a/public/language/en@pirate/topic.json +++ b/public/language/en@pirate/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "This topic will be moved to the category", "fork_topic_instruction": "Click the posts you want to fork", "fork_no_pids": "No posts selected!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Successfully forked topic! Click here to go to the forked topic.", "delete_posts_instruction": "Click the posts you want to delete/purge", "composer.title_placeholder": "Enter your topic title here...", diff --git a/public/language/en_US/topic.json b/public/language/en_US/topic.json index edcc8a8435..238f75eb0e 100644 --- a/public/language/en_US/topic.json +++ b/public/language/en_US/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "This topic will be moved to the category", "fork_topic_instruction": "Click the posts you want to fork", "fork_no_pids": "No posts selected!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Successfully forked topic! Click here to go to the forked topic.", "delete_posts_instruction": "Click the posts you want to delete/purge", "composer.title_placeholder": "Enter your topic title here...", diff --git a/public/language/es/topic.json b/public/language/es/topic.json index dd3d6bb709..b080634dbb 100644 --- a/public/language/es/topic.json +++ b/public/language/es/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Este tema será movido a la categoría", "fork_topic_instruction": "Pulsa en los mensajes que quieres dividir", "fork_no_pids": "¡No has seleccionado ningún mensaje!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "¡Se ha creado un nuevo tema a partir del original! Haz click aquí para ir al nuevo tema.", "delete_posts_instruction": "Haz click en los mensajes que quieres eliminar/limpiar", "composer.title_placeholder": "Ingresa el título de tu tema...", diff --git a/public/language/et/topic.json b/public/language/et/topic.json index 622c2b6982..0e236f149d 100644 --- a/public/language/et/topic.json +++ b/public/language/et/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "See teema liigutatakse antud kategooriasse", "fork_topic_instruction": "Vajuta postitustele, mida soovid forkida", "fork_no_pids": "Sa ei ole postitusi valinud!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Edukalt ''forkisid'' teema! Vajuta siia, et vaadata loodud teemat.", "delete_posts_instruction": "Klikka postitustel, mida tahad kustutada/puhastada", "composer.title_placeholder": "Sisesta teema pealkiri siia...", diff --git a/public/language/fa_IR/topic.json b/public/language/fa_IR/topic.json index 45fca81ea5..adaf0d29f6 100644 --- a/public/language/fa_IR/topic.json +++ b/public/language/fa_IR/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "این موضوع جابه‌جا خواهد شد به دستهٔ", "fork_topic_instruction": "پست‌هایی را که می‌خواهید به موضوع تازه ببرید، انتخاب کنید", "fork_no_pids": "هیچ پستی انتخاب نشده!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "موضوع با موفقیت منشعب شد! برای رفتن به موضوع انشعابی اینجا را کلیک کنید.", "delete_posts_instruction": "با کلیک بر روی پست شما می خواهید به حذف/پاکسازی", "composer.title_placeholder": "عنوان موضوعتان را اینجا بنویسید...", diff --git a/public/language/fi/topic.json b/public/language/fi/topic.json index b2d5e9d127..b17e0664ab 100644 --- a/public/language/fi/topic.json +++ b/public/language/fi/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Tämä keskustelu siirretään aihealueelle", "fork_topic_instruction": "Napsauta viestejä, jotka haluat haaroittaa", "fork_no_pids": "Ei valittuja viestejä!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Successfully forked topic! Click here to go to the forked topic.", "delete_posts_instruction": "Click the posts you want to delete/purge", "composer.title_placeholder": "Syötä aiheesi otsikko tähän...", diff --git a/public/language/fr/login.json b/public/language/fr/login.json index b3c80182b9..72fa0ef401 100644 --- a/public/language/fr/login.json +++ b/public/language/fr/login.json @@ -8,5 +8,5 @@ "failed_login_attempt": "Identification échouée", "login_successful": "Vous êtes maintenant connecté !", "dont_have_account": "Vous n'avez pas de compte ?", - "logged-out-due-to-inactivity": "You have been logged out of the Admin Control Panel due to inactivity" + "logged-out-due-to-inactivity": "Vous avez été déconnecté du Panneau de Contrôle d'Administration en raison de votre inactivité" } \ No newline at end of file diff --git a/public/language/fr/topic.json b/public/language/fr/topic.json index dc8bb65354..10cce54b2d 100644 --- a/public/language/fr/topic.json +++ b/public/language/fr/topic.json @@ -26,8 +26,8 @@ "tools": "Outils", "flag": "Signaler", "locked": "Verrouillé", - "pinned": "Pinned", - "moved": "Moved", + "pinned": "Épinglé", + "moved": "Déplacé", "bookmark_instructions": "Cliquez ici pour retourner au dernier message lu de ce fil.", "flag_title": "Signaler ce message à la modération", "flag_success": "Ce message a bien été signalé aux modérateurs.", @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Ce sujet sera déplacé vers la catégorie", "fork_topic_instruction": "Cliquez sur les postes à scinder", "fork_no_pids": "Aucun post sélectionné !", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Sujet copié avec succès ! Cliquez ici pour aller au sujet copié.", "delete_posts_instruction": "Sélectionnez les messages que vous souhaitez supprimer/vider", "composer.title_placeholder": "Entrer le titre du sujet ici…", diff --git a/public/language/gl/topic.json b/public/language/gl/topic.json index 96c8da628e..ab5fe853c3 100644 --- a/public/language/gl/topic.json +++ b/public/language/gl/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Este tema será movido á categoría", "fork_topic_instruction": "Fai clic nas publicacións que queiras dividir", "fork_no_pids": "Non seleccionaches ninguna publicación!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Creouse un novo tema a partir do orixinal! Fai clic aquí para ir ó novo tema.", "delete_posts_instruction": "Fai clic nas mensaxes que queres eliminar/limpar", "composer.title_placeholder": "Introduce o título do teu tema", diff --git a/public/language/he/topic.json b/public/language/he/topic.json index 8bf3fe2cda..dd0f7ad03f 100644 --- a/public/language/he/topic.json +++ b/public/language/he/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "נושא זה יועבר לקטגוריה", "fork_topic_instruction": "לחץ על הפוסטים שברצונך לשכפל", "fork_no_pids": "לא בחרת אף פוסט!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "הפוסט שוכפל בהצלחה! לחץ כאן על מנת לעבור לפוסט המשוכפל.", "delete_posts_instruction": "לחץ על הפוסטים שברצונך למחוק", "composer.title_placeholder": "הכנס את כותרת הנושא כאן...", diff --git a/public/language/hu/topic.json b/public/language/hu/topic.json index ef9dcb52b3..47c83d78ae 100644 --- a/public/language/hu/topic.json +++ b/public/language/hu/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Ez a téma ebbe a kategóriába lesz mozgatva", "fork_topic_instruction": "Klikkelj azokra a hozzászólásokra, amiket szét akarsz szedni", "fork_no_pids": "Nincs hozzászólás kiválasztva!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Successfully forked topic! Click here to go to the forked topic.", "delete_posts_instruction": "Click the posts you want to delete/purge", "composer.title_placeholder": "Írd be a témanevet...", diff --git a/public/language/id/topic.json b/public/language/id/topic.json index 757bc1b54f..4595b97798 100644 --- a/public/language/id/topic.json +++ b/public/language/id/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Topik ini akan dipindahkan ke kategori", "fork_topic_instruction": "Klik posting yang kamu ingin cabangkan", "fork_no_pids": "Tidak ada posting yang dipilih!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Topik berhasil dicabangkan! Klik disini untuk menuju topik yang telah dicabangkan.", "delete_posts_instruction": "Click the posts you want to delete/purge", "composer.title_placeholder": "Masukkan judul topik di sini...", diff --git a/public/language/it/topic.json b/public/language/it/topic.json index ccfdcec340..1834ff19cd 100644 --- a/public/language/it/topic.json +++ b/public/language/it/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Questa discussione verrà spostata nella categoria", "fork_topic_instruction": "Clicca sui post che vuoi dividere", "fork_no_pids": "Nessun post selezionato!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Topic Diviso con successo ! Clicca qui per andare al Topic Diviso.", "delete_posts_instruction": "Clicca sui post che vuoi cancellare/eliminare", "composer.title_placeholder": "Inserisci qui il titolo della discussione...", diff --git a/public/language/ja/topic.json b/public/language/ja/topic.json index 4fc666f07a..a6d8c5bbf0 100644 --- a/public/language/ja/topic.json +++ b/public/language/ja/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "スレッドはこちらのカテゴリへ移動", "fork_topic_instruction": "フォークしたいポストをクリックして", "fork_no_pids": "ポストが選択されていません!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "トピックをフォークするのに成功しました。ここを押して、このフォークしたトピックに行きます。", "delete_posts_instruction": "削除または粛清するには、当てはまる投稿を押してください", "composer.title_placeholder": "スレッドのタイトルを入力して...", diff --git a/public/language/ko/topic.json b/public/language/ko/topic.json index 122525bb38..756b2d0824 100644 --- a/public/language/ko/topic.json +++ b/public/language/ko/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "이 주제를 지정한 카테고리로 이동합니다.", "fork_topic_instruction": "분리할 게시물을 선택하세요.", "fork_no_pids": "게시물이 선택되지 않았습니다.", + "fork_pid_count": "%1 post(s) selected", "fork_success": "주제가 분리되었습니다! 분리된 주제를 보려면 여기를 클릭하세요.", "delete_posts_instruction": "삭제할 게시물을 선택하세요.", "composer.title_placeholder": "여기에 제목을 입력하세요.", diff --git a/public/language/lt/topic.json b/public/language/lt/topic.json index 4c8e07fc98..1aa37b4730 100644 --- a/public/language/lt/topic.json +++ b/public/language/lt/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Ši tema bus perkelta į kategoriją", "fork_topic_instruction": "Pažymėkite ant įrašų, kuriuos norite perkelti į naują temą", "fork_no_pids": "Nepasirinktas joks įrašas!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Sėkmingai išsišakota iš temos! Spausk čia kad nueitu į išsišakota temą", "delete_posts_instruction": "Click the posts you want to delete/purge", "composer.title_placeholder": "Įrašykite temos pavadinimą...", diff --git a/public/language/ms/topic.json b/public/language/ms/topic.json index 04b30e193d..c55222b87c 100644 --- a/public/language/ms/topic.json +++ b/public/language/ms/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Topik ini akan dipindahkan kepada kategori", "fork_topic_instruction": "Klik kiriman yang anda hendak salin", "fork_no_pids": "Tiada kiriman yang dipilih", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Berjaya menyalin topik. Klik sini untuk ke topik yang disalin.", "delete_posts_instruction": "Click the posts you want to delete/purge", "composer.title_placeholder": "Masukkan tajuk topik disini", diff --git a/public/language/nb/topic.json b/public/language/nb/topic.json index fe18a3d9f9..98049be51f 100644 --- a/public/language/nb/topic.json +++ b/public/language/nb/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Dette emnet vil bli flyttet til kategorien", "fork_topic_instruction": "Trykk på innleggene du vil forgrene", "fork_no_pids": "Ingen innlegg valgt!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Dette emnet ble forgrenet! Klikk for å gå til forgrenet emne.", "delete_posts_instruction": "Click the posts you want to delete/purge", "composer.title_placeholder": "Skriv din tråd-tittel her", diff --git a/public/language/nl/topic.json b/public/language/nl/topic.json index 337f02bbea..8a7a93ba7e 100644 --- a/public/language/nl/topic.json +++ b/public/language/nl/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Dit onderwerp zal naar de categorie verplaatst worden", "fork_topic_instruction": "Klik op de berichten die afgesplitst moeten worden", "fork_no_pids": "Geen berichten geselecteerd!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Onderwerp is succesvol afgesplitst. Klik hier om het nieuwe onderwerp te zien.", "delete_posts_instruction": "Klik op de berichten die verwijderd moeten worden", "composer.title_placeholder": "Voer hier de titel van het onderwerp in...", diff --git a/public/language/pl/topic.json b/public/language/pl/topic.json index 2c5cd28d2a..8c6ed0d56b 100644 --- a/public/language/pl/topic.json +++ b/public/language/pl/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Ten temat zostanie przeniesiony do kategorii", "fork_topic_instruction": "Zaznacz posty, które chcesz sklonować", "fork_no_pids": "Nie zaznaczyłeś żadnych postów!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Udało się skopiować temat. Kliknij tutaj, aby do niego przejść.", "delete_posts_instruction": "Kliknij na posty, które chcesz usunąć", "composer.title_placeholder": "Wpisz tutaj tytuł tematu...", diff --git a/public/language/pt_BR/topic.json b/public/language/pt_BR/topic.json index 760fe42a3f..dec0d42e8e 100644 --- a/public/language/pt_BR/topic.json +++ b/public/language/pt_BR/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Este tópico será movido para a categoria", "fork_topic_instruction": "Clique nos posts que você quer ramificar", "fork_no_pids": "Nenhum post selecionado!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Tópico ramificado com sucesso! Clique aqui para ir ao tópico ramificado.", "delete_posts_instruction": "Clique nos posts que você deseja deletar/limpar", "composer.title_placeholder": "Digite aqui o título para o seu tópico...", diff --git a/public/language/ro/topic.json b/public/language/ro/topic.json index 0daf15f7ec..0a9b94434b 100644 --- a/public/language/ro/topic.json +++ b/public/language/ro/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Acest subiect va fi mutat în categoria", "fork_topic_instruction": "Apasă pe mesajele care vrei sa le bifurci", "fork_no_pids": "Nu a fost selectat nici un mesaj!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Successfully forked topic! Click here to go to the forked topic.", "delete_posts_instruction": "Click the posts you want to delete/purge", "composer.title_placeholder": "Introdu numele subiectului aici ...", diff --git a/public/language/ru/topic.json b/public/language/ru/topic.json index 9ccfff5668..0912a92c32 100644 --- a/public/language/ru/topic.json +++ b/public/language/ru/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Эта тема будет перенесена в категорию", "fork_topic_instruction": "Отметьте сообщения для ответвления", "fork_no_pids": "Сообщения не отмечены!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Готово! Нажмите для перехода в отделённую тему.", "delete_posts_instruction": "Отметьте сообщения, которые Вы хотите удалить/очистить", "composer.title_placeholder": "Введите название темы...", diff --git a/public/language/rw/topic.json b/public/language/rw/topic.json index bd05fdfc3a..09f54f891f 100644 --- a/public/language/rw/topic.json +++ b/public/language/rw/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Iki kiganiro kirimurirwa mu cyiciro", "fork_topic_instruction": "Kanda ku byashizweho ushaka kugabanyaho", "fork_no_pids": "Nta kintu wahisemo!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Umaze kugabanyaho ku kiganiro! Kanda hano ugezwe ku kiganiro cyavutse. ", "delete_posts_instruction": "Kanda ku bintu ushaka guhisha/gusiba", "composer.title_placeholder": "Shyira umutwe w'ikiganiro cyawe aha...", diff --git a/public/language/sc/topic.json b/public/language/sc/topic.json index 97fb268bc0..1cc32bab64 100644 --- a/public/language/sc/topic.json +++ b/public/language/sc/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Custa arresonada at a èssere mòvida in sa creze", "fork_topic_instruction": "Sèbera is arresonos chi boles partzire", "fork_no_pids": "Perunu arresonu seberadu!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Successfully forked topic! Click here to go to the forked topic.", "delete_posts_instruction": "Click the posts you want to delete/purge", "composer.title_placeholder": "Pone su tìtulu de s'arresonada inoghe...", diff --git a/public/language/sk/topic.json b/public/language/sk/topic.json index 78c8473ae0..95eade8db2 100644 --- a/public/language/sk/topic.json +++ b/public/language/sk/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Táto téma bude presunutá do kategórie", "fork_topic_instruction": "Vyber príspevky, ktoré chceš oddeliť", "fork_no_pids": "Žiadne príspevky neboli vybrané!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Successfully forked topic! Click here to go to the forked topic.", "delete_posts_instruction": "Click the posts you want to delete/purge", "composer.title_placeholder": "Vlož nadpis témy sem...", diff --git a/public/language/sl/topic.json b/public/language/sl/topic.json index cc00affa99..92012a4925 100644 --- a/public/language/sl/topic.json +++ b/public/language/sl/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Ta tema bo premaknjena v to kategorijo", "fork_topic_instruction": "Klikni na objavo, ki o želiš odcepiti", "fork_no_pids": "Ni izbranih objav!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Uspešno ste razcepili temo! Klikni tu za ogled te teme.", "delete_posts_instruction": "Click the posts you want to delete/purge", "composer.title_placeholder": "Vpiši naslov teme...", diff --git a/public/language/sr/topic.json b/public/language/sr/topic.json index 42b56929a3..e43df818ad 100644 --- a/public/language/sr/topic.json +++ b/public/language/sr/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "This topic will be moved to the category", "fork_topic_instruction": "Click the posts you want to fork", "fork_no_pids": "No posts selected!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Successfully forked topic! Click here to go to the forked topic.", "delete_posts_instruction": "Click the posts you want to delete/purge", "composer.title_placeholder": "Enter your topic title here...", diff --git a/public/language/sv/topic.json b/public/language/sv/topic.json index 734afb5719..99fad2d42b 100644 --- a/public/language/sv/topic.json +++ b/public/language/sv/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Detta ämne kommer att flyttas till kategorin", "fork_topic_instruction": "Klicka på de inlägg du vill grena", "fork_no_pids": "Inga inlägg valda!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Ämnet har blivit förgrenat. Klicka här för att gå till det förgrenade ämnet.", "delete_posts_instruction": "Klicka på inläggen du vill radera/rensa bort", "composer.title_placeholder": "Skriv in ämnets titel här...", diff --git a/public/language/th/topic.json b/public/language/th/topic.json index 532af2a8a8..fa4e0bccc4 100644 --- a/public/language/th/topic.json +++ b/public/language/th/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "กระทู้นี้จะถูกย้ายไปที่หมวดหมู่", "fork_topic_instruction": "คลิกที่โพสที่คุณต้องการที่จะแยก", "fork_no_pids": "ไม่มีโพสต์ที่เลือก!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Successfully forked topic! Click here to go to the forked topic.", "delete_posts_instruction": "Click the posts you want to delete/purge", "composer.title_placeholder": "ป้อนชื่อกระทู้ของคุณที่นี่ ...", diff --git a/public/language/tr/topic.json b/public/language/tr/topic.json index b870308c74..8854a5eab9 100644 --- a/public/language/tr/topic.json +++ b/public/language/tr/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Bu konu kategorisine taşınacak", "fork_topic_instruction": "Ayırmak istediğiniz iletileri tıklayın", "fork_no_pids": "Hiç bir ileti seçilmedi!", + "fork_pid_count": "%1 ileti(ler) seçildi", "fork_success": "Başlık başarıyla ayrıldı!", "delete_posts_instruction": "Silmek/temizlemek istediğiniz iletilere tıklayın.", "composer.title_placeholder": "Başlık ismini buraya girin...", diff --git a/public/language/vi/topic.json b/public/language/vi/topic.json index 8c7085fcbf..3035b9ac9d 100644 --- a/public/language/vi/topic.json +++ b/public/language/vi/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Chủ đề này sẽ được chuyển tới phần mục", "fork_topic_instruction": "Chọn vào bài gửi mà bạn muốn fork", "fork_no_pids": "Chưa chọn bài gửi nào!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Tạo bản sao thành công! Nhấn vào đây để chuyển tới chủ đề vừa tạo.", "delete_posts_instruction": "Chọn những bài viết bạn muốn xoá", "composer.title_placeholder": "Nhập tiêu đề cho chủ đề của bạn tại đây...", diff --git a/public/language/zh_CN/topic.json b/public/language/zh_CN/topic.json index 63ebe02f77..072da54e1a 100644 --- a/public/language/zh_CN/topic.json +++ b/public/language/zh_CN/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "此主题将被移动到版块", "fork_topic_instruction": "点击将分割的帖子", "fork_no_pids": "未选中帖子!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "成功分割主题! 点这里跳转到分割后的主题。", "delete_posts_instruction": "点击想要删除/永久删除的帖子", "composer.title_placeholder": "在此输入您主题的标题...", diff --git a/public/language/zh_TW/topic.json b/public/language/zh_TW/topic.json index 87bb2d8e08..30d46b9419 100644 --- a/public/language/zh_TW/topic.json +++ b/public/language/zh_TW/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "這個主題將會被移動到類別", "fork_topic_instruction": "點擊要作為主題的文章", "fork_no_pids": "尚未選擇文章!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "成功分叉成新的主題!點擊這裡進入新的主題。", "delete_posts_instruction": "點擊你想要刪除/清除的張貼", "composer.title_placeholder": "輸入標題...", From ab858855145c009f1928f13d9925d1db337a9d1a Mon Sep 17 00:00:00 2001 From: Aziz Khoury Date: Wed, 10 Aug 2016 10:44:48 -0400 Subject: [PATCH 13/63] nodebb-plugin-spam-be-gone@0.4.10 https://github.com/akhoury/nodebb-plugin-spam-be-gone/issues/49 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fde24ac2ec..c9ad9c178f 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "nodebb-plugin-markdown": "6.0.2", "nodebb-plugin-mentions": "1.1.3", "nodebb-plugin-soundpack-default": "0.1.6", - "nodebb-plugin-spam-be-gone": "0.4.9", + "nodebb-plugin-spam-be-gone": "0.4.10", "nodebb-rewards-essentials": "0.0.9", "nodebb-theme-lavender": "3.0.13", "nodebb-theme-persona": "4.1.20", From 936149bb389b4788adf765389831938a68851bcf Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Wed, 10 Aug 2016 09:48:01 -0500 Subject: [PATCH 14/63] grant topics:delete by default --- src/categories/create.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/categories/create.js b/src/categories/create.js index 4f00da8149..8dcc936ebc 100644 --- a/src/categories/create.js +++ b/src/categories/create.js @@ -48,7 +48,7 @@ module.exports = function(Categories) { function(data, next) { category = data.category; - var defaultPrivileges = ['find', 'read', 'topics:read', 'topics:create', 'topics:reply', 'posts:edit', 'posts:delete', 'upload:post:image']; + var defaultPrivileges = ['find', 'read', 'topics:read', 'topics:create', 'topics:reply', 'posts:edit', 'posts:delete', 'topics:delete', 'upload:post:image']; async.series([ async.apply(db.setObject, 'category:' + category.cid, category), From 9e7d90e314d9e8ac23027c31a7b990a854fdc0e4 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Wed, 10 Aug 2016 12:29:25 -0400 Subject: [PATCH 15/63] allowing listeners to cancel an ajaxify request via ajaxify.start client-side hook --- public/src/ajaxify.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/public/src/ajaxify.js b/public/src/ajaxify.js index ba6222f06c..97a52724d2 100644 --- a/public/src/ajaxify.js +++ b/public/src/ajaxify.js @@ -66,6 +66,11 @@ $(document).ready(function() { url = ajaxify.start(url); + // If any listeners alter url and set it to an empty string, abort the ajaxification + if (url === '') { + return false; + } + previousBodyClass = ajaxify.data.bodyClass; $('#footer, #content').removeClass('hide').addClass('ajaxifying'); @@ -107,9 +112,13 @@ $(document).ready(function() { ajaxify.start = function(url) { url = ajaxify.removeRelativePath(url.replace(/^\/|\/$/g, '')); - $(window).trigger('action:ajaxify.start', {url: url}); + var payload = { + url: url + } - return url; + $(window).trigger('action:ajaxify.start', payload); + + return payload.url; }; ajaxify.updateHistory = function(url, quiet) { From e019eb40c4e01127d67679fcd80bfe41e571015b Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Wed, 10 Aug 2016 12:50:41 -0400 Subject: [PATCH 16/63] altering ajaxify abort behaviour to look for null instead of empty string, and triggering ajaxify.end when abort occurs --- public/src/ajaxify.js | 3 ++- public/src/client/footer.js | 8 +++++--- public/src/client/topic.js | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/public/src/ajaxify.js b/public/src/ajaxify.js index 97a52724d2..de20693eb0 100644 --- a/public/src/ajaxify.js +++ b/public/src/ajaxify.js @@ -67,7 +67,8 @@ $(document).ready(function() { url = ajaxify.start(url); // If any listeners alter url and set it to an empty string, abort the ajaxification - if (url === '') { + if (url === null) { + $(window).trigger('action:ajaxify.end', {url: url, tpl_url: ajaxify.data.template.name, title: ajaxify.data.title}); return false; } diff --git a/public/src/client/footer.js b/public/src/client/footer.js index f1d05d4bfe..30da71aa12 100644 --- a/public/src/client/footer.js +++ b/public/src/client/footer.js @@ -50,10 +50,12 @@ define('forum/footer', ['notifications', 'chat', 'components', 'translator'], fu } $(window).on('action:ajaxify.end', function(ev, data) { - var tid = data.url.match(/^topic\/(\d+)/); + if (data.url) { + var tid = data.url.match(/^topic\/(\d+)/); - if (tid && tid[1]) { - delete unreadTopics[tid[1]]; + if (tid && tid[1]) { + delete unreadTopics[tid[1]]; + } } }); diff --git a/public/src/client/topic.js b/public/src/client/topic.js index da4e5456e8..aff00909d1 100644 --- a/public/src/client/topic.js +++ b/public/src/client/topic.js @@ -31,7 +31,7 @@ define('forum/topic', [ $(window).off('keydown', onKeyDown); } - if (!data.url.startsWith('topic/')) { + if (data.url && !data.url.startsWith('topic/')) { require(['search'], function(search) { if (search.topicDOM.active) { search.topicDOM.end(); From 037b901e8519a41d896b69d261ebbff1b9262a3f Mon Sep 17 00:00:00 2001 From: barisusakli Date: Wed, 10 Aug 2016 21:28:22 +0300 Subject: [PATCH 17/63] closes #4919 --- public/language/en_GB/error.json | 3 ++ src/privileges/topics.js | 48 ++++++++++++++++++++----------- src/views/admin/settings/post.tpl | 4 +++ 3 files changed, 39 insertions(+), 16 deletions(-) diff --git a/public/language/en_GB/error.json b/public/language/en_GB/error.json index fa73ccfa8a..8dc3df4b02 100644 --- a/public/language/en_GB/error.json +++ b/public/language/en_GB/error.json @@ -67,6 +67,9 @@ "post-delete-duration-expired-days": "You are only allowed to delete posts for %1 day(s) after posting", "post-delete-duration-expired-days-hours": "You are only allowed to delete posts for %1 day(s) %2 hour(s) after posting", + "cant-delete-topic-has-reply": "You can't delete your topic after it has %1 reply", + "cant-delete-topic-has-replies": "You can't delete your topic after it has %1 replies", + "content-too-short": "Please enter a longer post. Posts should contain at least %1 character(s).", "content-too-long": "Please enter a shorter post. Posts can't be longer than %1 character(s).", "title-too-short": "Please enter a longer title. Titles should contain at least %1 character(s).", diff --git a/src/privileges/topics.js b/src/privileges/topics.js index c3a61fd317..7caffc06c3 100644 --- a/src/privileges/topics.js +++ b/src/privileges/topics.js @@ -3,6 +3,7 @@ var async = require('async'); +var meta = require('../meta'); var topics = require('../topics'); var user = require('../user'); var helpers = require('./helpers'); @@ -182,25 +183,40 @@ module.exports = function(privileges) { }; privileges.topics.canDelete = function(tid, uid, callback) { - topics.getTopicField(tid, 'cid', function(err, cid) { + var topicData; + async.waterfall([ + function(next) { + topics.getTopicFields(tid, ['cid', 'postcount'], next); + }, + function(_topicData, next) { + topicData = _topicData; + async.parallel({ + isModerator: async.apply(user.isModerator, uid, topicData.cid), + isAdministrator: async.apply(user.isAdministrator, uid), + isOwner: async.apply(topics.isOwner, tid, uid), + 'topics:delete': async.apply(helpers.isUserAllowedTo, 'topics:delete', uid, [topicData.cid]) + }, next); + } + ], function(err, results) { if (err) { return callback(err); } - helpers.some([ - async.apply(user.isModerator, uid, cid), - async.apply(user.isAdministrator, uid), - function(next) { - async.parallel({ - owner: async.apply(topics.isOwner, tid, uid), - 'topics:delete': async.apply(helpers.isUserAllowedTo, 'topics:delete', uid, [cid]) - }, function(err, result) { - if (err) { - return next(err); - } - next(null, result.owner && result['topics:delete'][0]); - }); - } - ], callback); + + if (results.isModerator || results.isAdministrator) { + return callback(null, true); + } + + var preventTopicDeleteAfterReplies = parseInt(meta.config.preventTopicDeleteAfterReplies, 10) || 0; + if (preventTopicDeleteAfterReplies && (topicData.postcount - 1) >= preventTopicDeleteAfterReplies) { + var langKey = preventTopicDeleteAfterReplies > 1 ? 'cant-delete-topic-has-replies' : 'cant-delete-topic-has-reply'; + return callback(new Error('[[error:' + langKey + ', ' + meta.config.preventTopicDeleteAfterReplies + ']]')); + } + + if (!results['topics:delete'][0]) { + return callback(null, false); + } + + callback(null, results.isOwner); }); }; diff --git a/src/views/admin/settings/post.tpl b/src/views/admin/settings/post.tpl index 4ac9aa3d2a..f58f524aca 100644 --- a/src/views/admin/settings/post.tpl +++ b/src/views/admin/settings/post.tpl @@ -52,6 +52,10 @@ +
    + + +
    From 73e19fa13aa7474864afd2217c7d06f86baf0543 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Wed, 10 Aug 2016 22:53:30 +0300 Subject: [PATCH 18/63] fix app.alertError --- public/src/client/topic/postTools.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/public/src/client/topic/postTools.js b/public/src/client/topic/postTools.js index 41aa3d4ca4..85a8986a4b 100644 --- a/public/src/client/topic/postTools.js +++ b/public/src/client/topic/postTools.js @@ -35,7 +35,7 @@ define('forum/topic/postTools', ['share', 'navigator', 'components', 'translator socket.emit('posts.loadPostTools', {pid: pid, cid: ajaxify.data.cid}, function(err, data) { if (err) { - return app.alertError(err); + return app.alertError(err.message); } data.posts.display_move_tools = data.posts.display_move_tools && index !== 0; @@ -384,11 +384,11 @@ define('forum/topic/postTools', ['share', 'navigator', 'components', 'translator className: 'vote-modal', show: true }); - + dialog.on('click', function() { dialog.modal('hide'); }); - + }); }); }); From 56d325bd869a07a0c95ec9a7cffd3658a9718b68 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Wed, 10 Aug 2016 23:55:49 +0300 Subject: [PATCH 19/63] privilege fixes --- public/src/client/topic/posts.js | 4 ++-- src/posts/edit.js | 4 ++-- src/posts/tools.js | 4 ++-- src/privileges/posts.js | 34 +++++++++++++++++--------------- src/privileges/topics.js | 4 ++-- src/socket.io/posts/tools.js | 5 +++-- src/topics/create.js | 11 +++++------ src/topics/fork.js | 4 ++-- 8 files changed, 36 insertions(+), 34 deletions(-) diff --git a/public/src/client/topic/posts.js b/public/src/client/topic/posts.js index 33be04f993..b31b5fc0ed 100644 --- a/public/src/client/topic/posts.js +++ b/public/src/client/topic/posts.js @@ -27,8 +27,8 @@ define('forum/topic/posts', [ data.privileges = ajaxify.data.privileges; data.posts.forEach(function(post) { post.selfPost = !!app.user.uid && parseInt(post.uid, 10) === parseInt(app.user.uid, 10); - post.display_edit_tools = (ajaxify.data.privileges.editOwnPosts && post.selfPost) || ajaxify.data.privileges.isAdminOrMod; - post.display_delete_tools = (ajaxify.data.privileges.deleteOwnPosts && post.selfPost) || ajaxify.data.privileges.isAdminOrMod; + post.display_edit_tools = (ajaxify.data.privileges['posts:edit'] && post.selfPost) || ajaxify.data.privileges.isAdminOrMod; + post.display_delete_tools = (ajaxify.data.privileges['posts:delete'] && post.selfPost) || ajaxify.data.privileges.isAdminOrMod; post.display_moderator_tools = post.display_edit_tools || post.display_delete_tools; post.display_move_tools = ajaxify.data.privileges.isAdminOrMod; post.display_post_menu = ajaxify.data.privileges.isAdminOrMod || post.selfPost || ((app.user.uid || ajaxify.data.postSharing.length) && !post.deleted); diff --git a/src/posts/edit.js b/src/posts/edit.js index e8af9ae2d4..e1df94aa9f 100644 --- a/src/posts/edit.js +++ b/src/posts/edit.js @@ -28,8 +28,8 @@ module.exports = function(Posts) { privileges.posts.canEdit(data.pid, data.uid, next); }, function (canEdit, next) { - if (!canEdit) { - return next(new Error('[[error:no-privileges]]')); + if (!canEdit.flag) { + return next(new Error(canEdit.message)); } Posts.getPostData(data.pid, next); }, diff --git a/src/posts/tools.js b/src/posts/tools.js index 40d150d049..e2573554e8 100644 --- a/src/posts/tools.js +++ b/src/posts/tools.js @@ -37,8 +37,8 @@ module.exports = function(Posts) { privileges.posts.canDelete(pid, uid, next); }, function (canDelete, next) { - if (!canDelete) { - return next(new Error('[[error:no-privileges]]')); + if (!canDelete.flag) { + return next(new Error(canDelete.message)); } if (isDelete) { diff --git a/src/privileges/posts.js b/src/privileges/posts.js index fe43a631c6..8ebf9e4bcb 100644 --- a/src/privileges/posts.js +++ b/src/privileges/posts.js @@ -147,15 +147,10 @@ module.exports = function(privileges) { return callback(err); } if (results.isAdminOrMod) { - return callback(null, true); + return callback(null, {flag: true}); } - if (results.isEditable.isLocked) { - return callback(new Error('[[error:topic-locked]]')); - } - if (results.isEditable.isEditExpired) { - return callback(new Error('[[error:post-edit-duration-expired, ' + meta.config.postEditDuration + ']]')); - } - callback(null, results.isEditable.editable); + + callback(null, results.isEditable); }); }; @@ -178,20 +173,25 @@ module.exports = function(privileges) { if (err) { return callback(err); } + if (results.isAdminOrMod) { - return callback(null, true); + return callback(null, {flag: true}); } + if (results.isLocked) { - return callback(new Error('[[error:topic-locked]]')); + return callback(null, {flag: false, message: '[[error:topic-locked]]'}); } + if (!results['posts:delete']) { - return callback(null, false); + return callback(null, {flag: false, message: '[[error:no-privileges]]'}); } + var postDeleteDuration = parseInt(meta.config.postDeleteDuration, 10); if (postDeleteDuration && (Date.now() - parseInt(postData.timestamp, 10) > postDeleteDuration * 1000)) { - return callback(new Error('[[error:post-delete-duration-expired, ' + meta.config.postDeleteDuration + ']]')); + return callback(null, {flag: false, message: '[[error:post-delete-duration-expired, ' + meta.config.postDeleteDuration + ']]'}); } - callback(null, results.isOwner); + + callback(null, {flag: results.isOwner, message: '[[error:no-privileges]]'}); }); }; @@ -223,20 +223,22 @@ module.exports = function(privileges) { }; function isPostEditable(pid, uid, callback) { + var tid; async.waterfall([ function(next) { posts.getPostFields(pid, ['tid', 'timestamp'], next); }, function(postData, next) { + tid = postData.tid; var postEditDuration = parseInt(meta.config.postEditDuration, 10); if (postEditDuration && Date.now() - parseInt(postData.timestamp, 10) > postEditDuration * 1000) { - return callback(null, {isEditExpired: true}); + return callback(null, {flag: false, message: '[[error:post-edit-duration-expired, ' + meta.config.postEditDuration + ']]'}); } topics.isLocked(postData.tid, next); }, function(isLocked, next) { if (isLocked) { - return callback(null, {isLocked: true}); + return callback(null, {flag: false, message: '[[error:topic-locked]]'}); } async.parallel({ @@ -245,7 +247,7 @@ module.exports = function(privileges) { }, next); }, function(result, next) { - next(null, {editable: result.owner && result.edit}); + next(null, {flag: result.owner && result.edit, message: '[[error:no-privileges]]'}); } ], callback); } diff --git a/src/privileges/topics.js b/src/privileges/topics.js index 7caffc06c3..27a9243222 100644 --- a/src/privileges/topics.js +++ b/src/privileges/topics.js @@ -58,8 +58,8 @@ module.exports = function(privileges) { disabled: disabled, tid: tid, uid: uid, - editOwnPosts: results['posts:edit'][0], - deleteOwnPosts: results['posts:delete'][0] + 'posts:edit': (results['posts:edit'][0] && !locked) || isAdminOrMod, + 'posts:delete': (results['posts:delete'][0] && !locked) || isAdminOrMod }, callback); }); }; diff --git a/src/socket.io/posts/tools.js b/src/socket.io/posts/tools.js index dfc99ac2dc..91e8dca241 100644 --- a/src/socket.io/posts/tools.js +++ b/src/socket.io/posts/tools.js @@ -47,12 +47,13 @@ module.exports = function(SocketPosts) { if (err) { return callback(err); } + results.posts.tools = results.tools.tools; results.posts.deleted = parseInt(results.posts.deleted, 10) === 1; results.posts.favourited = results.favourited[0]; results.posts.selfPost = socket.uid && socket.uid === parseInt(results.posts.uid, 10); - results.posts.display_edit_tools = results.canEdit; - results.posts.display_delete_tools = results.canDelete; + results.posts.display_edit_tools = results.canEdit.flag; + results.posts.display_delete_tools = results.canDelete.flag; results.posts.display_moderator_tools = results.posts.display_edit_tools || results.posts.display_delete_tools; results.posts.display_move_tools = results.isAdminOrMod; callback(null, results); diff --git a/src/topics/create.js b/src/topics/create.js index 1b561cdcaa..c79e0758f4 100644 --- a/src/topics/create.js +++ b/src/topics/create.js @@ -191,25 +191,24 @@ module.exports = function(Topics) { function(_cid, next) { cid = _cid; async.parallel({ - exists: async.apply(Topics.exists, tid), - locked: async.apply(Topics.isLocked, tid), + topicData: async.apply(Topics.getTopicData, tid), canReply: async.apply(privileges.topics.can, 'topics:reply', tid, uid), - isAdmin: async.apply(user.isAdministrator, uid), - isModerator: async.apply(user.isModerator, uid, cid) + isAdminOrMod: async.apply(privileges.categories.isAdminOrMod, cid, uid), }, next); }, function(results, next) { - if (!results.exists) { + if (!results.topicData) { return next(new Error('[[error:no-topic]]')); } - if (results.locked && !results.isAdmin && !results.isModerator) { + if (parseInt(results.topicData.locked, 10) === 1 && !results.isAdminOrMod) { return next(new Error('[[error:topic-locked]]')); } if (!results.canReply) { return next(new Error('[[error:no-privileges]]')); } + guestHandleValid(data, next); }, function(next) { diff --git a/src/topics/fork.js b/src/topics/fork.js index b2e16f069d..fbc9cdb54c 100644 --- a/src/topics/fork.js +++ b/src/topics/fork.js @@ -61,8 +61,8 @@ module.exports = function(Topics) { function(_tid, next) { function move(pid, next) { privileges.posts.canEdit(pid, uid, function(err, canEdit) { - if(err || !canEdit) { - return next(err); + if (err || !canEdit.flag) { + return next(err || new Error(canEdit.message)); } Topics.movePostToTopic(pid, tid, next); From d7cda83c8e88484cc5421eabc2316eb6a7bea2d7 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Thu, 11 Aug 2016 00:12:15 +0300 Subject: [PATCH 20/63] fix lang key --- public/language/en_GB/error.json | 2 +- src/privileges/topics.js | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/public/language/en_GB/error.json b/public/language/en_GB/error.json index 8dc3df4b02..319f5005b6 100644 --- a/public/language/en_GB/error.json +++ b/public/language/en_GB/error.json @@ -67,7 +67,7 @@ "post-delete-duration-expired-days": "You are only allowed to delete posts for %1 day(s) after posting", "post-delete-duration-expired-days-hours": "You are only allowed to delete posts for %1 day(s) %2 hour(s) after posting", - "cant-delete-topic-has-reply": "You can't delete your topic after it has %1 reply", + "cant-delete-topic-has-reply": "You can't delete your topic after it has a reply", "cant-delete-topic-has-replies": "You can't delete your topic after it has %1 replies", "content-too-short": "Please enter a longer post. Posts should contain at least %1 character(s).", diff --git a/src/privileges/topics.js b/src/privileges/topics.js index 27a9243222..c9f0ec717a 100644 --- a/src/privileges/topics.js +++ b/src/privileges/topics.js @@ -208,8 +208,10 @@ module.exports = function(privileges) { var preventTopicDeleteAfterReplies = parseInt(meta.config.preventTopicDeleteAfterReplies, 10) || 0; if (preventTopicDeleteAfterReplies && (topicData.postcount - 1) >= preventTopicDeleteAfterReplies) { - var langKey = preventTopicDeleteAfterReplies > 1 ? 'cant-delete-topic-has-replies' : 'cant-delete-topic-has-reply'; - return callback(new Error('[[error:' + langKey + ', ' + meta.config.preventTopicDeleteAfterReplies + ']]')); + var langKey = preventTopicDeleteAfterReplies > 1 ? + '[[error:cant-delete-topic-has-replies, ' + meta.config.preventTopicDeleteAfterReplies + ']]': + '[[error:cant-delete-topic-has-reply]]'; + return callback(new Error(langKey)); } if (!results['topics:delete'][0]) { From 1d70dc0d8bcdd082dfcb83d7666676ba5f0f9687 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Thu, 11 Aug 2016 08:41:34 +0300 Subject: [PATCH 21/63] closes #4930 --- src/controllers/accounts/info.js | 22 +++++++++++++++------- src/user/data.js | 11 +++++++---- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/controllers/accounts/info.js b/src/controllers/accounts/info.js index 6662c60cd6..1117cb28c1 100644 --- a/src/controllers/accounts/info.js +++ b/src/controllers/accounts/info.js @@ -1,22 +1,30 @@ 'use strict'; -var async = require('async'), - _ = require('underscore'), +var async = require('async'); +var _ = require('underscore'); - user = require('../../user'), - helpers = require('../helpers'), - accountHelpers = require('./helpers'); +var user = require('../../user'); +var helpers = require('../helpers'); +var accountHelpers = require('./helpers'); var infoController = {}; infoController.get = function(req, res, next) { accountHelpers.getBaseUser(req.params.userslug, req.uid, function(err, userData) { + if (err) { + return next(err); + } + async.parallel({ ips: async.apply(user.getIPs, res.locals.uid, 4), history: async.apply(user.getModerationHistory, res.locals.uid), fields: async.apply(user.getUserFields, res.locals.uid, ['banned']) }, function(err, data) { - data = _.extend(userData, { + if (err) { + return next(err); + } + + userData = _.extend(userData, { ips: data.ips, history: data.history }, data.fields); @@ -24,7 +32,7 @@ infoController.get = function(req, res, next) { userData.title = '[[pages:account/info]]'; userData.breadcrumbs = helpers.buildBreadcrumbs([{text: userData.username, url: '/user/' + userData.userslug}, {text: '[[user:settings]]'}]); - res.render('account/info', data); + res.render('account/info', userData); }); }); }; diff --git a/src/user/data.js b/src/user/data.js index 8e179ca119..d5a25bf7b4 100644 --- a/src/user/data.js +++ b/src/user/data.js @@ -58,14 +58,15 @@ module.exports = function(User) { if (fields.indexOf('banned') !== -1) { // Also retrieve ban expiry for these users db.sortedSetScores('users:banned:expire', uids, function(err, scores) { - users = users.map(function(userObj, idx) { + users.forEach(function(userObj, idx) { userObj.banned_until = scores[idx] || 0; userObj.banned_until_readable = scores[idx] ? new Date(scores[idx]).toString() : 'Not Banned'; }); + modifyUserData(users, fieldsToRemove, callback); }); + } else { + modifyUserData(users, fieldsToRemove, callback); } - - modifyUserData(users, fieldsToRemove, callback); }); }; @@ -104,7 +105,9 @@ module.exports = function(User) { return; } - user.username = validator.escape(user.username ? user.username.toString() : ''); + if (user.hasOwnProperty('username')) { + user.username = validator.escape(user.username ? user.username.toString() : ''); + } if (user.password) { user.password = undefined; From 973e2083299eb7e80ee1a4e6a3e920f9ea239a61 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Thu, 11 Aug 2016 09:31:10 +0300 Subject: [PATCH 22/63] added banned:expire to user hash --- src/user.js | 33 +++------------------------------ src/user/admin.js | 29 ++++++++++++++++++++++++++++- src/user/data.js | 13 +------------ 3 files changed, 32 insertions(+), 43 deletions(-) diff --git a/src/user.js b/src/user.js index e4f2eb5f55..d04b7c8cce 100644 --- a/src/user.js +++ b/src/user.js @@ -91,7 +91,7 @@ var utils = require('../public/src/utils'); User.getUsers = function(uids, uid, callback) { var fields = ['uid', 'username', 'userslug', 'picture', 'status', 'flags', - 'banned', 'joindate', 'postcount', 'reputation', 'email:confirmed', 'lastonline']; + 'banned', 'banned:expire', 'joindate', 'postcount', 'reputation', 'email:confirmed', 'lastonline']; async.waterfall([ function (next) { @@ -118,6 +118,8 @@ var utils = require('../public/src/utils'); user.joindateISO = utils.toISOString(user.joindate); user.administrator = results.isAdmin[index]; user.banned = parseInt(user.banned, 10) === 1; + user.banned_until = parseInt(user['banned:expire'], 10) || 0; + user.banned_until_readable = user.banned_until ? new Date(user.banned_until).toString() : 'Not Banned'; user['email:confirmed'] = parseInt(user['email:confirmed'], 10) === 1; user.lastonlineISO = utils.toISOString(user.lastonline) || user.joindateISO; } @@ -258,35 +260,6 @@ var utils = require('../public/src/utils'); }); }; - User.isBanned = function(uid, callback) { - async.waterfall([ - async.apply(User.getUserField, uid, 'banned'), - function(banned, next) { - banned = parseInt(banned, 10) === 1; - if (!banned) { - return next(null, banned); - } else { - // If they are banned, see if the ban has expired - db.sortedSetScore('users:banned:expire', uid, function(err, score) { - var stillBanned = !score || Date.now() < score; - - if (!stillBanned) { - async.parallel([ - async.apply(db.sortedSetRemove.bind(db), 'users:banned:expire', uid), - async.apply(db.sortedSetRemove.bind(db), 'users:banned', uid), - async.apply(User.setUserField, uid, 'banned', 0) - ], function(err) { - next(err, false); - }); - } else { - next(err, true); - } - }); - } - } - ], callback); - }; - User.addInterstitials = function(callback) { plugins.registerHook('core', { hook: 'filter:register.interstitial', diff --git a/src/user/admin.js b/src/user/admin.js index cf09c0a4ed..e4384782ee 100644 --- a/src/user/admin.js +++ b/src/user/admin.js @@ -71,6 +71,7 @@ module.exports = function(User) { if (until > 0 && Date.now() < until) { tasks.push(async.apply(db.sortedSetAdd, 'users:banned:expire', until, uid)); + tasks.push(async.apply(User.setUserField, uid, 'banned:expire', until)); } else { until = 0; } @@ -91,7 +92,7 @@ module.exports = function(User) { User.unban = function(uid, callback) { async.waterfall([ function (next) { - User.setUserField(uid, 'banned', 0, next); + User.setUserFields(uid, {banned: 0, 'banned:expire': 0}, next); }, function (next) { db.sortedSetsRemove(['users:banned', 'users:banned:expire'], uid, next); @@ -103,6 +104,32 @@ module.exports = function(User) { ], callback); }; + User.isBanned = function(uid, callback) { + async.waterfall([ + async.apply(User.getUserFields, uid, ['banned', 'banned:expire']), + function(userData, next) { + var banned = parseInt(userData.banned, 10) === 1; + if (!banned) { + return next(null, banned); + } + + // If they are banned, see if the ban has expired + var stillBanned = !userData['banned:expire'] || Date.now() < userData['banned:expire']; + + if (stillBanned) { + return next(null, true); + } + async.parallel([ + async.apply(db.sortedSetRemove.bind(db), 'users:banned:expire', uid), + async.apply(db.sortedSetRemove.bind(db), 'users:banned', uid), + async.apply(User.setUserFields, uid, {banned:0, 'banned:expire': 0}) + ], function(err) { + next(err, false); + }); + } + ], callback); + }; + User.resetFlags = function(uids, callback) { if (!Array.isArray(uids) || !uids.length) { return callback(); diff --git a/src/user/data.js b/src/user/data.js index d5a25bf7b4..6f2a2dd4b7 100644 --- a/src/user/data.js +++ b/src/user/data.js @@ -55,18 +55,7 @@ module.exports = function(User) { return callback(err); } - if (fields.indexOf('banned') !== -1) { - // Also retrieve ban expiry for these users - db.sortedSetScores('users:banned:expire', uids, function(err, scores) { - users.forEach(function(userObj, idx) { - userObj.banned_until = scores[idx] || 0; - userObj.banned_until_readable = scores[idx] ? new Date(scores[idx]).toString() : 'Not Banned'; - }); - modifyUserData(users, fieldsToRemove, callback); - }); - } else { - modifyUserData(users, fieldsToRemove, callback); - } + modifyUserData(users, fieldsToRemove, callback); }); }; From 73c3da1a832d151e6429b62bbc7b514e48eb2f75 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Thu, 11 Aug 2016 09:52:05 +0300 Subject: [PATCH 23/63] dont check maximum group name length if it is a privilege group --- src/groups/create.js | 6 ++++-- src/socket.io/admin/categories.js | 4 ++-- src/socket.io/admin/groups.js | 5 +++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/groups/create.js b/src/groups/create.js index 353c0aca49..cf9b1eb784 100644 --- a/src/groups/create.js +++ b/src/groups/create.js @@ -9,7 +9,9 @@ var db = require('../database'); module.exports = function(Groups) { Groups.create = function(data, callback) { - var system = data.system === true || parseInt(data.system, 10) === 1 || data.name === 'administrators' || data.name === 'registered-users' || data.name === 'Global Moderators' || Groups.isPrivilegeGroup(data.name); + var system = data.system === true || parseInt(data.system, 10) === 1 || + data.name === 'administrators' || data.name === 'registered-users' || data.name === 'Global Moderators' || + Groups.isPrivilegeGroup(data.name); var groupData; var timestamp = data.timestamp || Date.now(); @@ -79,7 +81,7 @@ module.exports = function(Groups) { return callback(new Error('[[error:group-name-too-short]]')); } - if (name.length > (parseInt(meta.config.maximumGroupNameLength, 10) || 255)) { + if (!Groups.isPrivilegeGroup(data.name) && name.length > (parseInt(meta.config.maximumGroupNameLength, 10) || 255)) { return callback(new Error('[[error:group-name-too-long]]')); } diff --git a/src/socket.io/admin/categories.js b/src/socket.io/admin/categories.js index 8e24359e7a..ff2f8400b0 100644 --- a/src/socket.io/admin/categories.js +++ b/src/socket.io/admin/categories.js @@ -54,7 +54,7 @@ Categories.update = function(socket, data, callback) { }; Categories.setPrivilege = function(socket, data, callback) { - if(!data) { + if (!data) { return callback(new Error('[[error:invalid-data]]')); } @@ -72,7 +72,7 @@ Categories.getPrivilegeSettings = function(socket, cid, callback) { }; Categories.copyPrivilegesToChildren = function(socket, cid, callback) { - categories.getCategories([cid], socket.uid, function(err, categories) { + categories.getCategories([cid], socket.uid, function(err, categories) { if (err) { return callback(err); } diff --git a/src/socket.io/admin/groups.js b/src/socket.io/admin/groups.js index c912008210..0088fbc5c8 100644 --- a/src/socket.io/admin/groups.js +++ b/src/socket.io/admin/groups.js @@ -1,8 +1,9 @@ "use strict"; var async = require('async'); -var groups = require('../../groups'), - Groups = {}; +var groups = require('../../groups'); + +var Groups = {}; Groups.create = function(socket, data, callback) { if (!data) { From 6c11709cf16861dd3870c050c0c9414d80aa7bb8 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Thu, 11 Aug 2016 14:22:15 +0300 Subject: [PATCH 24/63] closes #4933 --- src/groups/create.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/groups/create.js b/src/groups/create.js index cf9b1eb784..ffbaf97448 100644 --- a/src/groups/create.js +++ b/src/groups/create.js @@ -81,7 +81,7 @@ module.exports = function(Groups) { return callback(new Error('[[error:group-name-too-short]]')); } - if (!Groups.isPrivilegeGroup(data.name) && name.length > (parseInt(meta.config.maximumGroupNameLength, 10) || 255)) { + if (!Groups.isPrivilegeGroup(name) && name.length > (parseInt(meta.config.maximumGroupNameLength, 10) || 255)) { return callback(new Error('[[error:group-name-too-long]]')); } From 413517a08444ed40fcdddf7191b179c2e9de2e24 Mon Sep 17 00:00:00 2001 From: Accalia de Elementia Date: Thu, 11 Aug 2016 12:36:27 +0000 Subject: [PATCH 25/63] feat(socket.io-groups): Allow first page of members to be retrieved via websockets previously requesting the first page of members of a group failed --- src/socket.io/groups.js | 82 +++++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 39 deletions(-) diff --git a/src/socket.io/groups.js b/src/socket.io/groups.js index 4e48a9649b..0b6423229e 100644 --- a/src/socket.io/groups.js +++ b/src/socket.io/groups.js @@ -1,23 +1,24 @@ "use strict"; -var async = require('async'), +var async = require('async'), groups = require('../groups'), meta = require('../meta'), user = require('../user'), + utils = require('../../../public/src/utils'), groupsController = require('../controllers/groups'), SocketGroups = {}; -SocketGroups.before = function(socket, method, data, next) { +SocketGroups.before = function (socket, method, data, next) { if (!data) { return next(new Error('[[error:invalid-data]]')); } next(); }; -SocketGroups.join = function(socket, data, callback) { +SocketGroups.join = function (socket, data, callback) { if (!parseInt(socket.uid, 10)) { return callback(new Error('[[error:invalid-uid]]')); } @@ -26,7 +27,7 @@ SocketGroups.join = function(socket, data, callback) { return callback(new Error('[[error:not-allowed]]')); } - groups.exists(data.groupName, function(err, exists) { + groups.exists(data.groupName, function (err, exists) { if (err || !exists) { return callback(err || new Error('[[error:no-group]]')); } @@ -38,7 +39,7 @@ SocketGroups.join = function(socket, data, callback) { async.parallel({ isAdmin: async.apply(user.isAdministrator, socket.uid), groupData: async.apply(groups.getGroupData, data.groupName) - }, function(err, results) { + }, function (err, results) { if (err) { return callback(err); } @@ -56,7 +57,7 @@ SocketGroups.join = function(socket, data, callback) { }); }; -SocketGroups.leave = function(socket, data, callback) { +SocketGroups.leave = function (socket, data, callback) { if (!parseInt(socket.uid, 10)) { return callback(new Error('[[error:invalid-uid]]')); } @@ -73,7 +74,7 @@ function isOwner(next) { async.parallel({ isAdmin: async.apply(user.isAdministrator, socket.uid), isOwner: async.apply(groups.ownership.isOwner, socket.uid, data.groupName) - }, function(err, results) { + }, function (err, results) { if (err || (!isOwner && !results.isAdmin)) { return callback(err || new Error('[[error:no-privileges]]')); } @@ -84,7 +85,7 @@ function isOwner(next) { function isInvited(next) { return function (socket, data, callback) { - groups.isInvited(socket.uid, data.groupName, function(err, invited) { + groups.isInvited(socket.uid, data.groupName, function (err, invited) { if (err || !invited) { return callback(err || new Error('[[error:not-invited]]')); } @@ -93,70 +94,70 @@ function isInvited(next) { }; } -SocketGroups.grant = isOwner(function(socket, data, callback) { +SocketGroups.grant = isOwner(function (socket, data, callback) { groups.ownership.grant(data.toUid, data.groupName, callback); }); -SocketGroups.rescind = isOwner(function(socket, data, callback) { +SocketGroups.rescind = isOwner(function (socket, data, callback) { groups.ownership.rescind(data.toUid, data.groupName, callback); }); -SocketGroups.accept = isOwner(function(socket, data, callback) { +SocketGroups.accept = isOwner(function (socket, data, callback) { groups.acceptMembership(data.groupName, data.toUid, callback); }); -SocketGroups.reject = isOwner(function(socket, data, callback) { +SocketGroups.reject = isOwner(function (socket, data, callback) { groups.rejectMembership(data.groupName, data.toUid, callback); }); -SocketGroups.acceptAll = isOwner(function(socket, data, callback) { +SocketGroups.acceptAll = isOwner(function (socket, data, callback) { acceptRejectAll(groups.acceptMembership, socket, data, callback); }); -SocketGroups.rejectAll = isOwner(function(socket, data, callback) { +SocketGroups.rejectAll = isOwner(function (socket, data, callback) { acceptRejectAll(groups.rejectMembership, socket, data, callback); }); function acceptRejectAll(method, socket, data, callback) { async.waterfall([ - function(next) { + function (next) { groups.getPending(data.groupName, next); }, - function(uids, next) { - async.each(uids, function(uid, next) { + function (uids, next) { + async.each(uids, function (uid, next) { method(data.groupName, uid, next); }, next); } ], callback); } -SocketGroups.issueInvite = isOwner(function(socket, data, callback) { +SocketGroups.issueInvite = isOwner(function (socket, data, callback) { groups.invite(data.groupName, data.toUid, callback); }); -SocketGroups.rescindInvite = isOwner(function(socket, data, callback) { +SocketGroups.rescindInvite = isOwner(function (socket, data, callback) { groups.rejectMembership(data.groupName, data.toUid, callback); }); -SocketGroups.acceptInvite = isInvited(function(socket, data, callback) { +SocketGroups.acceptInvite = isInvited(function (socket, data, callback) { groups.acceptMembership(data.groupName, socket.uid, callback); }); -SocketGroups.rejectInvite = isInvited(function(socket, data, callback) { +SocketGroups.rejectInvite = isInvited(function (socket, data, callback) { groups.rejectMembership(data.groupName, socket.uid, callback); }); -SocketGroups.update = isOwner(function(socket, data, callback) { +SocketGroups.update = isOwner(function (socket, data, callback) { groups.update(data.groupName, data.values, callback); }); -SocketGroups.kick = isOwner(function(socket, data, callback) { +SocketGroups.kick = isOwner(function (socket, data, callback) { if (socket.uid === parseInt(data.uid, 10)) { return callback(new Error('[[error:cant-kick-self]]')); } - groups.ownership.isOwner(data.uid, data.groupName, function(err, isOwner) { + groups.ownership.isOwner(data.uid, data.groupName, function (err, isOwner) { if (err) { return callback(err); } @@ -165,7 +166,7 @@ SocketGroups.kick = isOwner(function(socket, data, callback) { }); -SocketGroups.create = function(socket, data, callback) { +SocketGroups.create = function (socket, data, callback) { if (!socket.uid) { return callback(new Error('[[error:no-privileges]]')); } else if (parseInt(meta.config.allowGroupCreation, 10) !== 1) { @@ -179,7 +180,7 @@ SocketGroups.create = function(socket, data, callback) { groups.create(data, callback); }; -SocketGroups.delete = function(socket, data, callback) { +SocketGroups.delete = function (socket, data, callback) { if (data.groupName === 'administrators' || data.groupName === 'registered-users' || data.groupName === 'Global Moderators') { @@ -189,7 +190,7 @@ SocketGroups.delete = function(socket, data, callback) { async.parallel({ isOwner: async.apply(groups.ownership.isOwner, socket.uid, data.groupName), isAdmin: async.apply(user.isAdministrator, socket.uid) - }, function(err, checks) { + }, function (err, checks) { if (err) { return callback(err); } @@ -201,12 +202,12 @@ SocketGroups.delete = function(socket, data, callback) { }); }; -SocketGroups.search = function(socket, data, callback) { +SocketGroups.search = function (socket, data, callback) { data.options = data.options || {}; if (!data.query) { var groupsPerPage = 15; - groupsController.getGroupsFromSet(socket.uid, data.options.sort, 0, groupsPerPage - 1, function(err, data) { + groupsController.getGroupsFromSet(socket.uid, data.options.sort, 0, groupsPerPage - 1, function (err, data) { callback(err, !err ? data.groups : null); }); return; @@ -215,7 +216,7 @@ SocketGroups.search = function(socket, data, callback) { groups.search(data.query, data.options || {}, callback); }; -SocketGroups.loadMore = function(socket, data, callback) { +SocketGroups.loadMore = function (socket, data, callback) { if (!data.sort || !data.after) { return callback(); } @@ -226,33 +227,36 @@ SocketGroups.loadMore = function(socket, data, callback) { groupsController.getGroupsFromSet(socket.uid, data.sort, start, stop, callback); }; -SocketGroups.searchMembers = function(socket, data, callback) { +SocketGroups.searchMembers = function (socket, data, callback) { data.uid = socket.uid; groups.searchMembers(data, callback); }; -SocketGroups.loadMoreMembers = function(socket, data, callback) { - if (!data.groupName || !parseInt(data.after, 10)) { +SocketGroups.loadMoreMembers = function (socket, data, callback) { + if (!data.groupName || !utils.isNumber(data.after) || parseInt(data.after, 10) < 0) { return callback(new Error('[[error:invalid-data]]')); } data.after = parseInt(data.after, 10); - user.getUsersFromSet('group:' + data.groupName + ':members', socket.uid, data.after, data.after + 9, function(err, users) { + user.getUsersFromSet('group:' + data.groupName + ':members', socket.uid, data.after, data.after + 9, function (err, users) { if (err) { return callback(err); } - callback(null, {users: users, nextStart: data.after + 10}); + callback(null, { + users: users, + nextStart: data.after + 10 + }); }); }; SocketGroups.cover = {}; -SocketGroups.cover.update = function(socket, data, callback) { +SocketGroups.cover.update = function (socket, data, callback) { if (!socket.uid) { return callback(new Error('[[error:no-privileges]]')); } - groups.ownership.isOwner(socket.uid, data.groupName, function(err, isOwner) { + groups.ownership.isOwner(socket.uid, data.groupName, function (err, isOwner) { if (err || !isOwner) { return callback(err || new Error('[[error:no-privileges]]')); } @@ -261,12 +265,12 @@ SocketGroups.cover.update = function(socket, data, callback) { }); }; -SocketGroups.cover.remove = function(socket, data, callback) { +SocketGroups.cover.remove = function (socket, data, callback) { if (!socket.uid) { return callback(new Error('[[error:no-privileges]]')); } - groups.ownership.isOwner(socket.uid, data.groupName, function(err, isOwner) { + groups.ownership.isOwner(socket.uid, data.groupName, function (err, isOwner) { if (err || !isOwner) { return callback(err || new Error('[[error:no-privileges]]')); } From 574929337dff33060dece2d0c02910ac86fc7952 Mon Sep 17 00:00:00 2001 From: Accalia de Elementia Date: Thu, 11 Aug 2016 12:45:23 +0000 Subject: [PATCH 26/63] chore(whitespace): revert whitespace only changes --- src/socket.io/groups.js | 79 ++++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 41 deletions(-) diff --git a/src/socket.io/groups.js b/src/socket.io/groups.js index 0b6423229e..3b314f7d0a 100644 --- a/src/socket.io/groups.js +++ b/src/socket.io/groups.js @@ -1,6 +1,6 @@ "use strict"; -var async = require('async'), +var async = require('async'), groups = require('../groups'), meta = require('../meta'), @@ -11,14 +11,14 @@ var async = require('async'), SocketGroups = {}; -SocketGroups.before = function (socket, method, data, next) { +SocketGroups.before = function(socket, method, data, next) { if (!data) { return next(new Error('[[error:invalid-data]]')); } next(); }; -SocketGroups.join = function (socket, data, callback) { +SocketGroups.join = function(socket, data, callback) { if (!parseInt(socket.uid, 10)) { return callback(new Error('[[error:invalid-uid]]')); } @@ -27,7 +27,7 @@ SocketGroups.join = function (socket, data, callback) { return callback(new Error('[[error:not-allowed]]')); } - groups.exists(data.groupName, function (err, exists) { + groups.exists(data.groupName, function(err, exists) { if (err || !exists) { return callback(err || new Error('[[error:no-group]]')); } @@ -39,7 +39,7 @@ SocketGroups.join = function (socket, data, callback) { async.parallel({ isAdmin: async.apply(user.isAdministrator, socket.uid), groupData: async.apply(groups.getGroupData, data.groupName) - }, function (err, results) { + }, function(err, results) { if (err) { return callback(err); } @@ -57,7 +57,7 @@ SocketGroups.join = function (socket, data, callback) { }); }; -SocketGroups.leave = function (socket, data, callback) { +SocketGroups.leave = function(socket, data, callback) { if (!parseInt(socket.uid, 10)) { return callback(new Error('[[error:invalid-uid]]')); } @@ -74,7 +74,7 @@ function isOwner(next) { async.parallel({ isAdmin: async.apply(user.isAdministrator, socket.uid), isOwner: async.apply(groups.ownership.isOwner, socket.uid, data.groupName) - }, function (err, results) { + }, function(err, results) { if (err || (!isOwner && !results.isAdmin)) { return callback(err || new Error('[[error:no-privileges]]')); } @@ -85,7 +85,7 @@ function isOwner(next) { function isInvited(next) { return function (socket, data, callback) { - groups.isInvited(socket.uid, data.groupName, function (err, invited) { + groups.isInvited(socket.uid, data.groupName, function(err, invited) { if (err || !invited) { return callback(err || new Error('[[error:not-invited]]')); } @@ -94,70 +94,70 @@ function isInvited(next) { }; } -SocketGroups.grant = isOwner(function (socket, data, callback) { +SocketGroups.grant = isOwner(function(socket, data, callback) { groups.ownership.grant(data.toUid, data.groupName, callback); }); -SocketGroups.rescind = isOwner(function (socket, data, callback) { +SocketGroups.rescind = isOwner(function(socket, data, callback) { groups.ownership.rescind(data.toUid, data.groupName, callback); }); -SocketGroups.accept = isOwner(function (socket, data, callback) { +SocketGroups.accept = isOwner(function(socket, data, callback) { groups.acceptMembership(data.groupName, data.toUid, callback); }); -SocketGroups.reject = isOwner(function (socket, data, callback) { +SocketGroups.reject = isOwner(function(socket, data, callback) { groups.rejectMembership(data.groupName, data.toUid, callback); }); -SocketGroups.acceptAll = isOwner(function (socket, data, callback) { +SocketGroups.acceptAll = isOwner(function(socket, data, callback) { acceptRejectAll(groups.acceptMembership, socket, data, callback); }); -SocketGroups.rejectAll = isOwner(function (socket, data, callback) { +SocketGroups.rejectAll = isOwner(function(socket, data, callback) { acceptRejectAll(groups.rejectMembership, socket, data, callback); }); function acceptRejectAll(method, socket, data, callback) { async.waterfall([ - function (next) { + function(next) { groups.getPending(data.groupName, next); }, - function (uids, next) { - async.each(uids, function (uid, next) { + function(uids, next) { + async.each(uids, function(uid, next) { method(data.groupName, uid, next); }, next); } ], callback); } -SocketGroups.issueInvite = isOwner(function (socket, data, callback) { +SocketGroups.issueInvite = isOwner(function(socket, data, callback) { groups.invite(data.groupName, data.toUid, callback); }); -SocketGroups.rescindInvite = isOwner(function (socket, data, callback) { +SocketGroups.rescindInvite = isOwner(function(socket, data, callback) { groups.rejectMembership(data.groupName, data.toUid, callback); }); -SocketGroups.acceptInvite = isInvited(function (socket, data, callback) { +SocketGroups.acceptInvite = isInvited(function(socket, data, callback) { groups.acceptMembership(data.groupName, socket.uid, callback); }); -SocketGroups.rejectInvite = isInvited(function (socket, data, callback) { +SocketGroups.rejectInvite = isInvited(function(socket, data, callback) { groups.rejectMembership(data.groupName, socket.uid, callback); }); -SocketGroups.update = isOwner(function (socket, data, callback) { +SocketGroups.update = isOwner(function(socket, data, callback) { groups.update(data.groupName, data.values, callback); }); -SocketGroups.kick = isOwner(function (socket, data, callback) { +SocketGroups.kick = isOwner(function(socket, data, callback) { if (socket.uid === parseInt(data.uid, 10)) { return callback(new Error('[[error:cant-kick-self]]')); } - groups.ownership.isOwner(data.uid, data.groupName, function (err, isOwner) { + groups.ownership.isOwner(data.uid, data.groupName, function(err, isOwner) { if (err) { return callback(err); } @@ -166,7 +166,7 @@ SocketGroups.kick = isOwner(function (socket, data, callback) { }); -SocketGroups.create = function (socket, data, callback) { +SocketGroups.create = function(socket, data, callback) { if (!socket.uid) { return callback(new Error('[[error:no-privileges]]')); } else if (parseInt(meta.config.allowGroupCreation, 10) !== 1) { @@ -180,7 +180,7 @@ SocketGroups.create = function (socket, data, callback) { groups.create(data, callback); }; -SocketGroups.delete = function (socket, data, callback) { +SocketGroups.delete = function(socket, data, callback) { if (data.groupName === 'administrators' || data.groupName === 'registered-users' || data.groupName === 'Global Moderators') { @@ -190,7 +190,7 @@ SocketGroups.delete = function (socket, data, callback) { async.parallel({ isOwner: async.apply(groups.ownership.isOwner, socket.uid, data.groupName), isAdmin: async.apply(user.isAdministrator, socket.uid) - }, function (err, checks) { + }, function(err, checks) { if (err) { return callback(err); } @@ -202,12 +202,12 @@ SocketGroups.delete = function (socket, data, callback) { }); }; -SocketGroups.search = function (socket, data, callback) { +SocketGroups.search = function(socket, data, callback) { data.options = data.options || {}; if (!data.query) { var groupsPerPage = 15; - groupsController.getGroupsFromSet(socket.uid, data.options.sort, 0, groupsPerPage - 1, function (err, data) { + groupsController.getGroupsFromSet(socket.uid, data.options.sort, 0, groupsPerPage - 1, function(err, data) { callback(err, !err ? data.groups : null); }); return; @@ -216,7 +216,7 @@ SocketGroups.search = function (socket, data, callback) { groups.search(data.query, data.options || {}, callback); }; -SocketGroups.loadMore = function (socket, data, callback) { +SocketGroups.loadMore = function(socket, data, callback) { if (!data.sort || !data.after) { return callback(); } @@ -227,36 +227,33 @@ SocketGroups.loadMore = function (socket, data, callback) { groupsController.getGroupsFromSet(socket.uid, data.sort, start, stop, callback); }; -SocketGroups.searchMembers = function (socket, data, callback) { +SocketGroups.searchMembers = function(socket, data, callback) { data.uid = socket.uid; groups.searchMembers(data, callback); }; -SocketGroups.loadMoreMembers = function (socket, data, callback) { +SocketGroups.loadMoreMembers = function(socket, data, callback) { if (!data.groupName || !utils.isNumber(data.after) || parseInt(data.after, 10) < 0) { return callback(new Error('[[error:invalid-data]]')); } data.after = parseInt(data.after, 10); - user.getUsersFromSet('group:' + data.groupName + ':members', socket.uid, data.after, data.after + 9, function (err, users) { + user.getUsersFromSet('group:' + data.groupName + ':members', socket.uid, data.after, data.after + 9, function(err, users) { if (err) { return callback(err); } - callback(null, { - users: users, - nextStart: data.after + 10 - }); + callback(null, {users: users, nextStart: data.after + 10}); }); }; SocketGroups.cover = {}; -SocketGroups.cover.update = function (socket, data, callback) { +SocketGroups.cover.update = function(socket, data, callback) { if (!socket.uid) { return callback(new Error('[[error:no-privileges]]')); } - groups.ownership.isOwner(socket.uid, data.groupName, function (err, isOwner) { + groups.ownership.isOwner(socket.uid, data.groupName, function(err, isOwner) { if (err || !isOwner) { return callback(err || new Error('[[error:no-privileges]]')); } @@ -265,12 +262,12 @@ SocketGroups.cover.update = function (socket, data, callback) { }); }; -SocketGroups.cover.remove = function (socket, data, callback) { +SocketGroups.cover.remove = function(socket, data, callback) { if (!socket.uid) { return callback(new Error('[[error:no-privileges]]')); } - groups.ownership.isOwner(socket.uid, data.groupName, function (err, isOwner) { + groups.ownership.isOwner(socket.uid, data.groupName, function(err, isOwner) { if (err || !isOwner) { return callback(err || new Error('[[error:no-privileges]]')); } From 74a993ccb35df66fc02935fca564242edc290e59 Mon Sep 17 00:00:00 2001 From: Accalia de Elementia Date: Thu, 11 Aug 2016 12:57:06 +0000 Subject: [PATCH 27/63] fix: Use the correct path for utils --- src/socket.io/groups.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/socket.io/groups.js b/src/socket.io/groups.js index 3b314f7d0a..7d9ce46a70 100644 --- a/src/socket.io/groups.js +++ b/src/socket.io/groups.js @@ -5,7 +5,7 @@ var async = require('async'), groups = require('../groups'), meta = require('../meta'), user = require('../user'), - utils = require('../../../public/src/utils'), + utils = require('../../public/src/utils'), groupsController = require('../controllers/groups'), SocketGroups = {}; From 528964cbe4e1470c3fa0d980dc59d730c5d3aa12 Mon Sep 17 00:00:00 2001 From: NodeBB Misty Date: Thu, 11 Aug 2016 09:02:29 -0400 Subject: [PATCH 28/63] Latest translations and fallbacks --- 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@pirate/error.json | 1 + public/language/en_US/error.json | 1 + public/language/es/error.json | 1 + public/language/es/global.json | 2 +- public/language/es/topic.json | 4 ++-- 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/fr/topic.json | 2 +- public/language/gl/error.json | 1 + public/language/he/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/ms/error.json | 1 + public/language/nb/error.json | 1 + public/language/nl/error.json | 1 + public/language/pl/category.json | 8 ++++---- public/language/pl/error.json | 21 ++++++++++---------- public/language/pl/global.json | 8 ++++---- public/language/pl/login.json | 2 +- public/language/pl/pages.json | 4 ++-- public/language/pl/register.json | 8 ++++---- public/language/pl/topic.json | 12 ++++++------ public/language/pl/user.json | 6 +++--- public/language/pt_BR/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/vi/error.json | 29 ++++++++++++++-------------- public/language/vi/global.json | 4 ++-- public/language/vi/topic.json | 8 ++++---- public/language/zh_CN/error.json | 1 + public/language/zh_TW/error.json | 1 + 52 files changed, 98 insertions(+), 58 deletions(-) diff --git a/public/language/ar/error.json b/public/language/ar/error.json index 33ff273b6b..4717871d44 100644 --- a/public/language/ar/error.json +++ b/public/language/ar/error.json @@ -20,6 +20,7 @@ "email-taken": "البريد الالكتروني مأخوذ", "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.", "no-email-to-confirm": "هذا المنتدى يستلزم تفعيل بريدك الإلكتروني، انقر هنا من فضلك لإدخاله.", "email-confirm-failed": "لم نستطع تفعيل بريدك الإلكتروني، المرجو المحاولة لاحقًا.", "confirm-email-already-sent": "لقد تم ارسال بريد التأكيد، الرجاء اﻹنتظار 1% دقائق لإعادة اﻹرسال", diff --git a/public/language/bg/error.json b/public/language/bg/error.json index 076b6fb878..6a3ef24696 100644 --- a/public/language/bg/error.json +++ b/public/language/bg/error.json @@ -20,6 +20,7 @@ "email-taken": "Е-пощата е заета", "email-not-confirmed": "Вашата е-поща все още не е потвърдена. Моля, натиснете тук, за да потвърдите е-пощата си.", "email-not-confirmed-chat": "Няма да можете да пишете в разговори, докато е-пощата Ви не бъде потвърдена. Моля, натиснете тук, за да потвърдите е-пощата си.", + "email-not-confirmed-email-sent": "Вашата е-поща все още не е потвърдена. Моля, проверете входящата си кутия за писмото за потвърждение.", "no-email-to-confirm": "Този форум изисква потвърдена е-поща. Моля, натиснете тук, за да въведете е-поща", "email-confirm-failed": "Не успяхме да потвърдим е-пощата Ви. Моля, опитайте отново по-късно.", "confirm-email-already-sent": "Е-писмото за потвърждение вече е изпратено. Моля, почакайте още %1 минута/и, преди да изпратите ново.", diff --git a/public/language/bn/error.json b/public/language/bn/error.json index 9f8be3d140..6a07599afa 100644 --- a/public/language/bn/error.json +++ b/public/language/bn/error.json @@ -20,6 +20,7 @@ "email-taken": "ইমেইল আগেই ব্যবহৃত", "email-not-confirmed": "আপনার ইমেইল এড্রেস নিশ্চিত করা হয় নি, নিশ্চিত করতে এখানে ক্লিক করুন।", "email-not-confirmed-chat": "You are unable to chat until your email is confirmed, please click here to confirm your email.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "This forum requires email confirmation, please click here to enter an email", "email-confirm-failed": "We could not confirm your email, please try again later.", "confirm-email-already-sent": "Confirmation email already sent, please wait %1 minute(s) to send another one.", diff --git a/public/language/cs/error.json b/public/language/cs/error.json index 086b3b9eca..7162bf5ebd 100644 --- a/public/language/cs/error.json +++ b/public/language/cs/error.json @@ -20,6 +20,7 @@ "email-taken": "Email je již použit", "email-not-confirmed": "Vaše emailová adresa zatím nebyla potvrzena. Kliknutím zde svůj email potvrdíte.", "email-not-confirmed-chat": "You are unable to chat until your email is confirmed, please click here to confirm your email.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "This forum requires email confirmation, please click here to enter an email", "email-confirm-failed": "We could not confirm your email, please try again later.", "confirm-email-already-sent": "Potvrzovací email již byl odeslán. Vyčkejte %1 minut pokud chcete odeslat další.", diff --git a/public/language/da/error.json b/public/language/da/error.json index 6320e0e990..78e2b469c3 100644 --- a/public/language/da/error.json +++ b/public/language/da/error.json @@ -20,6 +20,7 @@ "email-taken": "Emailadresse allerede i brug", "email-not-confirmed": "Din email adresse er ikke blevet bekræftet endnu, venligst klik her for at bekrætige den.", "email-not-confirmed-chat": "Du kan ikke chatte før din email er bekræftet, klik her for at bekræfte din email.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "Dette forum kræver bekræftelse af din email, klik her for at indtaste en email", "email-confirm-failed": "Vi kunne ikke bekræfte din email, prøv igen senere.", "confirm-email-already-sent": "Bekræftelses email er allerede afsendt, vent venligt %1 minut(ter) for at sende endnu en.", diff --git a/public/language/de/error.json b/public/language/de/error.json index 6f7bd0e385..544aead1c3 100644 --- a/public/language/de/error.json +++ b/public/language/de/error.json @@ -20,6 +20,7 @@ "email-taken": "Die E-Mail-Adresse ist bereits vergeben", "email-not-confirmed": "Deine E-Mail wurde noch nicht bestätigt, bitte klicke hier, um deine E-Mail zu bestätigen.", "email-not-confirmed-chat": "Du kannst denn Chat erst nutzen wenn deine E-Mail bestätigt wurde, bitte klicke hier, um deine E-Mail zu bestätigen.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "Dieses Forum setzt eine E-Mail-Bestätigung voraus, bitte klicke hier um eine E-Mail-Adresse einzugeben.", "email-confirm-failed": "Wir konnten deine E-Mail-Adresse nicht bestätigen, bitte versuch es später noch einmal", "confirm-email-already-sent": "Die Bestätigungsmail wurde verschickt, bitte warte %1 Minute(n) um eine Weitere zu verschicken.", diff --git a/public/language/el/error.json b/public/language/el/error.json index 45f9f6b2fb..b7f9c621ed 100644 --- a/public/language/el/error.json +++ b/public/language/el/error.json @@ -20,6 +20,7 @@ "email-taken": "Το email είναι πιασμένο", "email-not-confirmed": "Your email has not been confirmed yet, please click here to confirm your email.", "email-not-confirmed-chat": "You are unable to chat until your email is confirmed, please click here to confirm your email.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "This forum requires email confirmation, please click here to enter an email", "email-confirm-failed": "We could not confirm your email, please try again later.", "confirm-email-already-sent": "Confirmation email already sent, please wait %1 minute(s) to send another one.", diff --git a/public/language/en@pirate/error.json b/public/language/en@pirate/error.json index 3a95ab7cc6..6a614b6de4 100644 --- a/public/language/en@pirate/error.json +++ b/public/language/en@pirate/error.json @@ -20,6 +20,7 @@ "email-taken": "Email taken", "email-not-confirmed": "Your email has not been confirmed yet, please click here to confirm your email.", "email-not-confirmed-chat": "You are unable to chat until your email is confirmed, please click here to confirm your email.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "This forum requires email confirmation, please click here to enter an email", "email-confirm-failed": "We could not confirm your email, please try again later.", "confirm-email-already-sent": "Confirmation email already sent, please wait %1 minute(s) to send another one.", diff --git a/public/language/en_US/error.json b/public/language/en_US/error.json index 3a95ab7cc6..6a614b6de4 100644 --- a/public/language/en_US/error.json +++ b/public/language/en_US/error.json @@ -20,6 +20,7 @@ "email-taken": "Email taken", "email-not-confirmed": "Your email has not been confirmed yet, please click here to confirm your email.", "email-not-confirmed-chat": "You are unable to chat until your email is confirmed, please click here to confirm your email.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "This forum requires email confirmation, please click here to enter an email", "email-confirm-failed": "We could not confirm your email, please try again later.", "confirm-email-already-sent": "Confirmation email already sent, please wait %1 minute(s) to send another one.", diff --git a/public/language/es/error.json b/public/language/es/error.json index 723aa9beb6..0df59adbad 100644 --- a/public/language/es/error.json +++ b/public/language/es/error.json @@ -20,6 +20,7 @@ "email-taken": "Correo electrónico ocupado", "email-not-confirmed": "Su cuenta de correo electrónico no ha sido confirmada aún, por favor haga click aquí para confirmarla.", "email-not-confirmed-chat": "No puedes usar el chat hasta que confirmes tu dirección de correo electrónico, por favor haz click aquí para confirmar tu correo.", + "email-not-confirmed-email-sent": "Tu correo electrónico está sin confirmar, por favor busca el correo de confirmación en tu bandeja de entrada.", "no-email-to-confirm": "Este foro requiere confirmación de su email, por favor pulse aquí para introducir un email", "email-confirm-failed": "No se ha podido confirmar su email, por favor inténtelo de nuevo más tarde.", "confirm-email-already-sent": "El email de confirmación ya ha sido enviado, por favor espera %1 minuto(s) para enviar otro.", diff --git a/public/language/es/global.json b/public/language/es/global.json index fbe548dd54..79fd9c1a88 100644 --- a/public/language/es/global.json +++ b/public/language/es/global.json @@ -48,7 +48,7 @@ "online": "Conectado", "users": "Usuarios", "topics": "Temas", - "posts": "Posts", + "posts": "Mensajes", "best": "Mejor valorados", "upvoters": "Positivos", "upvoted": "Votado positivamente", diff --git a/public/language/es/topic.json b/public/language/es/topic.json index b080634dbb..a1bdf48ff4 100644 --- a/public/language/es/topic.json +++ b/public/language/es/topic.json @@ -80,13 +80,13 @@ "loading_more_posts": "Cargando más publicaciones", "move_topic": "Mover tema", "move_topics": "Mover temas", - "move_post": "Mover publicación", + "move_post": "Mover mensaje", "post_moved": "¡Publicación movida correctamente!", "fork_topic": "Dividir tema", "topic_will_be_moved_to": "Este tema será movido a la categoría", "fork_topic_instruction": "Pulsa en los mensajes que quieres dividir", "fork_no_pids": "¡No has seleccionado ningún mensaje!", - "fork_pid_count": "%1 post(s) selected", + "fork_pid_count": "%1 mensaje(s) seleccionados", "fork_success": "¡Se ha creado un nuevo tema a partir del original! Haz click aquí para ir al nuevo tema.", "delete_posts_instruction": "Haz click en los mensajes que quieres eliminar/limpiar", "composer.title_placeholder": "Ingresa el título de tu tema...", diff --git a/public/language/et/error.json b/public/language/et/error.json index 02713277b5..48024ec16a 100644 --- a/public/language/et/error.json +++ b/public/language/et/error.json @@ -20,6 +20,7 @@ "email-taken": "Email on võetud", "email-not-confirmed": "Su emaili aadress ei ole kinnitatud, vajuta siia et kinnitada.", "email-not-confirmed-chat": "Sõnumeid ei ole võimalik enne saata kui sinu email on kinnitatud. Kinnitamiseks vajuta siia.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "See foorum nõuab emaili kinnitust, palun vajuta siia, et sisestada email", "email-confirm-failed": "Meil ei õnnestunud sinu emaili kinnitada, proovi hiljem uuesti.", "confirm-email-already-sent": "Kinnituskiri on juba saadetud, palun oota %1 minut(it) uue kirja saatmiseks.", diff --git a/public/language/fa_IR/error.json b/public/language/fa_IR/error.json index d4661f4c8d..0b79d81e23 100644 --- a/public/language/fa_IR/error.json +++ b/public/language/fa_IR/error.json @@ -20,6 +20,7 @@ "email-taken": "این ایمیل گرفته شده است.", "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.", "no-email-to-confirm": "ایمیل شما تایید نشده است ، لطفا برای وارد کردن ایمیل اینجا کلیک کنید", "email-confirm-failed": "سیستم موفق به تایید ایمیل شما نشد، لطفا بعدا دوباره سعی کنید", "confirm-email-already-sent": "ایمیل فعال‌سازی قبلا فرستاده شده، لطفا %1 دقیقه صبر کنید تا ایمیل دیگری بفرستید.", diff --git a/public/language/fi/error.json b/public/language/fi/error.json index e728dcfc78..8862df7356 100644 --- a/public/language/fi/error.json +++ b/public/language/fi/error.json @@ -20,6 +20,7 @@ "email-taken": "Sähköpostiosoite varattu", "email-not-confirmed": "Sähköpostiasi ei ole vielä vahvistettu, ole hyvä ja napsauta tätä vahvistaaksesi sen.", "email-not-confirmed-chat": "Et voi keskustella ennen kuin sähköpostiosoitteesi on vahvistettu, ole hyvä ja paina tästä vahvistaaksesi sen.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "This forum requires email confirmation, please click here to enter an email", "email-confirm-failed": "We could not confirm your email, please try again later.", "confirm-email-already-sent": "Confirmation email already sent, please wait %1 minute(s) to send another one.", diff --git a/public/language/fr/error.json b/public/language/fr/error.json index f62e4043ff..0a494e47ab 100644 --- a/public/language/fr/error.json +++ b/public/language/fr/error.json @@ -20,6 +20,7 @@ "email-taken": "Email déjà utilisé", "email-not-confirmed": "Votre adresse email n'est pas confirmée, cliquez ici pour la valider.", "email-not-confirmed-chat": "Il ne vous est pas possible d'utiliser le chat tant que votre adresse email n'a pas été vérifiée. Veuillez cliquer ici pour confirmer votre adresse email.", + "email-not-confirmed-email-sent": "Votre adresse email n'a pas encore été confirmée. Merci de vérifier l'email de confirmation dans votre boîte de reception.", "no-email-to-confirm": "Ce forum requiert une vérification de votre adresse email. Veuillez cliquer ici pour entrer une adresse.", "email-confirm-failed": "Votre adresse email n'a pas pu être vérifiée. Veuillez ré-essayer plus tard.", "confirm-email-already-sent": "L'email de confirmation a déjà été envoyé. Veuillez attendre %1 minute(s) avant de redemander un nouvel envoi.", diff --git a/public/language/fr/topic.json b/public/language/fr/topic.json index 10cce54b2d..0a2f7ae7b3 100644 --- a/public/language/fr/topic.json +++ b/public/language/fr/topic.json @@ -86,7 +86,7 @@ "topic_will_be_moved_to": "Ce sujet sera déplacé vers la catégorie", "fork_topic_instruction": "Cliquez sur les postes à scinder", "fork_no_pids": "Aucun post sélectionné !", - "fork_pid_count": "%1 post(s) selected", + "fork_pid_count": "%1 message(s) sélectionné(s)", "fork_success": "Sujet copié avec succès ! Cliquez ici pour aller au sujet copié.", "delete_posts_instruction": "Sélectionnez les messages que vous souhaitez supprimer/vider", "composer.title_placeholder": "Entrer le titre du sujet ici…", diff --git a/public/language/gl/error.json b/public/language/gl/error.json index 8944015afd..76bdf60486 100644 --- a/public/language/gl/error.json +++ b/public/language/gl/error.json @@ -20,6 +20,7 @@ "email-taken": "Correo en uso", "email-not-confirmed": "O teu correo aínda non está confirmado, por favor pica aquí para confirmalo.", "email-not-confirmed-chat": "Non podes charlar ata que confirmes o teu correo, por favor pica aquí para confirmalo.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "Este foro require confirmación de correo, por favor pica aquí para introducir un correo.", "email-confirm-failed": "Non podemos confirmar o teu correo, por favor téntao de novo máis tarde.", "confirm-email-already-sent": "O correo de confirmación foi enviado, agarda %1 minute(s) para enviar outro.", diff --git a/public/language/he/error.json b/public/language/he/error.json index 3696f40550..7b00a4a288 100644 --- a/public/language/he/error.json +++ b/public/language/he/error.json @@ -20,6 +20,7 @@ "email-taken": "כתובת אימייל תפוסה", "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.", "no-email-to-confirm": "פורום זה דורש אישור בדוא\"ל, אנא לחץ כאן כדי להכניס לדואר אלקטרוני", "email-confirm-failed": "לא הצלחנו לאשר את הדוא\"ל שלך, תנסה שוב אחר כך", "confirm-email-already-sent": "מייל האישור כבר נשלח, אנא המתן %1 דקות כדי לשלוח מייל נוסף.", diff --git a/public/language/hu/error.json b/public/language/hu/error.json index 19a14975ea..ce999c9ead 100644 --- a/public/language/hu/error.json +++ b/public/language/hu/error.json @@ -20,6 +20,7 @@ "email-taken": "Foglalt e-mail", "email-not-confirmed": "Az e-mail címed még nem lett ellenőrizve, kérlek kattints ide az e-mail címed ellenőrzéséhez!", "email-not-confirmed-chat": "You are unable to chat until your email is confirmed, please click here to confirm your email.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "Ez a fórum e-mail megerősítést kíván, kérlek kattints ide egy cím beírásához", "email-confirm-failed": "Nem tudtuk ellenőrizni az e-mail címedet, kérlek próbálkozz később.", "confirm-email-already-sent": "Confirmation email already sent, please wait %1 minute(s) to send another one.", diff --git a/public/language/id/error.json b/public/language/id/error.json index 111505a95d..822698d462 100644 --- a/public/language/id/error.json +++ b/public/language/id/error.json @@ -20,6 +20,7 @@ "email-taken": "Email sudah terdaftar", "email-not-confirmed": "Email kamu belum dikonfirmasi, klik disini untuk mengkonfirmasi email.", "email-not-confirmed-chat": "You are unable to chat until your email is confirmed, please click here to confirm your email.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "This forum requires email confirmation, please click here to enter an email", "email-confirm-failed": "We could not confirm your email, please try again later.", "confirm-email-already-sent": "Confirmation email already sent, please wait %1 minute(s) to send another one.", diff --git a/public/language/it/error.json b/public/language/it/error.json index 740211d54e..e2ff61bf88 100644 --- a/public/language/it/error.json +++ b/public/language/it/error.json @@ -20,6 +20,7 @@ "email-taken": "Email già esistente", "email-not-confirmed": "La tua Email deve essere ancora confermata, per favore clicca qui per confermare la tua Email.", "email-not-confirmed-chat": "Non potrai chattare finchè non avrai confermato la tua email, per favore clicca qui per farlo ora.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "Questo forum richiede la conferma dell'indirizzo email, per favore clicca qui per inserirne uno", "email-confirm-failed": "Non possiamo confermare la tua email, per favore prova ancora più tardi.", "confirm-email-already-sent": "Email di conferma già inviata, per favore attendere %1 minuti per richiederne un'altra.", diff --git a/public/language/ja/error.json b/public/language/ja/error.json index 786ca3988a..ba607d9c09 100644 --- a/public/language/ja/error.json +++ b/public/language/ja/error.json @@ -20,6 +20,7 @@ "email-taken": "メールアドレスは既に使われています", "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.", "no-email-to-confirm": "このフォーラムを利用するにはメールアドレスの確認を行う必要があります。メールアドレスを確認するためにはここをクリックしてください。", "email-confirm-failed": "メールアドレスの確認が出来ませんでした。再度お試しください。", "confirm-email-already-sent": "確認のメールは既に送信されています。再度送信するには、%1分後に再度お試しください。", diff --git a/public/language/ko/error.json b/public/language/ko/error.json index 45b2c548d8..1a0e568eb3 100644 --- a/public/language/ko/error.json +++ b/public/language/ko/error.json @@ -20,6 +20,7 @@ "email-taken": "이미 사용 중인 이메일입니다.", "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.", "no-email-to-confirm": "이메일 인증이 필요합니다. 이곳을 클릭하여 이메일 입력하세요.", "email-confirm-failed": "이메일 인증이 실패하였습니다. 잠시 후에 다시 시도하세요.", "confirm-email-already-sent": "인증 메일이 이미 발송되었습니다. %1 분 이후에 재 발송이 가능합니다.", diff --git a/public/language/lt/error.json b/public/language/lt/error.json index 01c1a1d505..a1c40b2542 100644 --- a/public/language/lt/error.json +++ b/public/language/lt/error.json @@ -20,6 +20,7 @@ "email-taken": "El. pašto adresas jau užimtas", "email-not-confirmed": "Jūsų el. paštas nepatvirtintas, prašome paspausti čia norint jį patvirtinti.", "email-not-confirmed-chat": "Jūs negalite bendrauti, kol jūsų el.paštas nėra patvirtintas, prašome spausti čia kad aktyvuoti jūsų el.paštą", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "Šis forumas reikalauja patvirtinimo el. paštu prašome spausti čia el. adreso įrašymui", "email-confirm-failed": "Negalime patvirtinti jūsų el. adreso, prašom bandyti vėliau.", "confirm-email-already-sent": "Patvirtinimo laiškas išsiųstas, prašome palaukti %1 minute(s) kad išsiųstume kita", diff --git a/public/language/ms/error.json b/public/language/ms/error.json index f90fd5f3b3..d7b0fed05c 100644 --- a/public/language/ms/error.json +++ b/public/language/ms/error.json @@ -20,6 +20,7 @@ "email-taken": "Emel telah digunakan", "email-not-confirmed": "Emel anda belum disahkan lagi, sila klik sini untuk mengesahkan emel anda.", "email-not-confirmed-chat": "Anda tidak dibenarkan sembang sehingga emel disahkan, sila sahkan emel anda.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "Forum ini memerlukan pengesahan emel, sila klik sini untuk memasukkan emel", "email-confirm-failed": "Kami tidak dapat memastikan emel anda, sila cuba lagi nanti", "confirm-email-already-sent": "Pengesahan emel telah dihantar, sila tunggu %1 minit() untuk menghantar yang baru.", diff --git a/public/language/nb/error.json b/public/language/nb/error.json index 416c950043..b2df20d45c 100644 --- a/public/language/nb/error.json +++ b/public/language/nb/error.json @@ -20,6 +20,7 @@ "email-taken": "E-post opptatt", "email-not-confirmed": "E-posten din har ikke blitt bekreftet enda, vennligst klikk for å bekrefte din e-post.", "email-not-confirmed-chat": "Du kan ikke chatte før e-posten din er bekreftet, vennligst klikk her for å bekrefte e-postadressen.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "Dette forumet krever e-postbekreftelse, vennligst klikk her for å skrive inn en e-post", "email-confirm-failed": "Vi kunne ikke bekrefte e-posten din, vennligst prøv igjen senere.", "confirm-email-already-sent": "E-post for bekreftelse er allerede sendt, vennligst vent %1 minutt(er) for å sende en til.", diff --git a/public/language/nl/error.json b/public/language/nl/error.json index e66ba5134d..c22b6ec22c 100644 --- a/public/language/nl/error.json +++ b/public/language/nl/error.json @@ -20,6 +20,7 @@ "email-taken": "E-mailadres is al in gebruik", "email-not-confirmed": "Het e-mailadres van dit account is nog niet bevestigd, klik hier om je e-mailadres te bevestigen.", "email-not-confirmed-chat": "Het gebruik van chatfunctionaliteit is pas toegestaan na validatie van het e-mailadres.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "Dit berichtenforum vereist bevestiging per e-mail, klik hier om een e-mailadres te registreren", "email-confirm-failed": "Helaas kon het e-mailadres niet bevestigd worden, probeer het later nog eens.", "confirm-email-already-sent": "Bevestigingsmail is zojuist al verzonden, wacht alsjeblieft %1 minuut (minuten) voordat je opnieuw een bevestigingsmail aanvraagt.", diff --git a/public/language/pl/category.json b/public/language/pl/category.json index e4053aa931..bbbdeee94c 100644 --- a/public/language/pl/category.json +++ b/public/language/pl/category.json @@ -10,10 +10,10 @@ "share_this_category": "Udostępnij tę kategorię", "watch": "Obserwuj", "ignore": "Ignoruj", - "watching": "Watching", - "ignoring": "Ignoring", - "watching.description": "Show topics in unread", - "ignoring.description": "Do not show topics in unread", + "watching": "Obserwowanie", + "ignoring": "Ignorowanie", + "watching.description": "Pokaż tematy jako nieprzeczytane", + "ignoring.description": "Nie pokazuj tematów jako nieprzeczytane", "watch.message": "Obserwujesz teraz uaktualnienia z tej kategorii", "ignore.message": "Ignorujesz teraz uaktualnienia z tej kategorii", "watched-categories": "Obserwowane kategorie" diff --git a/public/language/pl/error.json b/public/language/pl/error.json index 627f7e061b..0a887ccf89 100644 --- a/public/language/pl/error.json +++ b/public/language/pl/error.json @@ -20,6 +20,7 @@ "email-taken": "Email zajęty", "email-not-confirmed": "Twój email nie został jeszcze potwierdzony. Proszę kliknąć tutaj by go potwierdzić.", "email-not-confirmed-chat": "Nie możesz prowadzić rozmów dopóki twój email nie zostanie potwierdzony, kliknij tutaj, aby potwierdzić swój email.", + "email-not-confirmed-email-sent": "Twój e-mail jeszcze nie został potwierdzony, proszę sprawdź swoją skrzynkę odbiorczą.", "no-email-to-confirm": "To forum wymaga weryfikacji przez email. Proszę kliknąć tutaj, aby wprowadzić adres.", "email-confirm-failed": "Nie byliśmy w stanie potwierdzić twojego email-a. Proszę spróbować później.", "confirm-email-already-sent": "Email potwierdzający został już wysłany, proszę odczekaj jeszcze %1 minut(y), aby wysłać kolejny.", @@ -30,7 +31,7 @@ "user-banned": "Użytkownik zbanowany", "user-too-new": "Przepraszamy, musisz odczekać %1 sekund(y) przed utworzeniem pierwszego posta", "blacklisted-ip": "Twój adres IP został zablokowany na tej społeczności. Jeśli uważasz to za błąd, zgłoś to administratorowi", - "ban-expiry-missing": "Please provide an end date for this ban", + "ban-expiry-missing": "Wprowadź datę końca blokady", "no-category": "Kategoria nie istnieje", "no-topic": "Temat nie istnieje", "no-post": "Post nie istnieje", @@ -47,13 +48,13 @@ "post-edit-duration-expired-hours-minutes": "Możesz edytować posty tylko przez %1 godzin(y) i %2 minut(y) po ich napisaniu", "post-edit-duration-expired-days": "Możesz edytować posty tylko przez %1 dzień (dni) po ich napisaniu", "post-edit-duration-expired-days-hours": "Możesz edytować posty tylko przez %1 dzień (dni) i %2 godzin(y) po ich napisaniu", - "post-delete-duration-expired": "You are only allowed to delete posts for %1 second(s) after posting", - "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-days-hours": "You are only allowed to delete posts for %1 day(s) %2 hour(s) after posting", + "post-delete-duration-expired": "Możesz kasować posty przez %1 sekund(-y) po napisaniu", + "post-delete-duration-expired-minutes": "Możesz kasować posty przez %1 minut(-y) po napisaniu", + "post-delete-duration-expired-minutes-seconds": "Możesz kasować posty przez %1 minut(-y) i %2 sekund(-y) po napisaniu", + "post-delete-duration-expired-hours": "Możesz kasować posty przez %1 godzin(-y) po napisaniu", + "post-delete-duration-expired-hours-minutes": "Możesz kasować posty przez %1 godzin(-y) i %2 minut(-y) po napisaniu", + "post-delete-duration-expired-days": "Możesz kasować posty przez %1 dni po napisaniu", + "post-delete-duration-expired-days-hours": "Możesz kasować posty przez %1 dni i %2 godzin(-y) po napisaniu", "content-too-short": "Prosimy wpisać dłuższy post. Posty powinny zawierać co najmniej %1 znaków.", "content-too-long": "Prosimy wpisać krótszy post. Posty nie mogą zawierać więcej niż %1 znaków.", "title-too-short": "Prosimy podać dłuższy tytuł. Tytuły powinny zawierać co najmniej %1 znaków.", @@ -76,7 +77,7 @@ "invalid-image-extension": "Błędne rozszerzenie pliku", "invalid-file-type": "Błędny typ pliku. Dozwolone typy to: %1", "group-name-too-short": "Nazwa grupy za krótka", - "group-name-too-long": "Group name too long", + "group-name-too-long": "Nazwa grupy jest za długa", "group-already-exists": "Grupa już istnieje", "group-name-change-not-allowed": "Nie można zmieniać nazwy tej grupy.", "group-already-member": "Już jesteś członkiem tej grupy", @@ -119,6 +120,6 @@ "not-in-room": "Użytkownik nie jest w pokoju", "no-users-in-room": "Brak użytkowników w pokoju", "cant-kick-self": "Nie możesz wyrzucić samego siebie z grupy", - "no-users-selected": "No user(s) selected", + "no-users-selected": "Nie wybrano żadnych użytkowników", "invalid-home-page-route": "Invalid home page route" } \ No newline at end of file diff --git a/public/language/pl/global.json b/public/language/pl/global.json index bd9821c5b0..946993295c 100644 --- a/public/language/pl/global.json +++ b/public/language/pl/global.json @@ -50,10 +50,10 @@ "topics": "Tematy", "posts": "Posty", "best": "Najlepsze", - "upvoters": "Upvoters", - "upvoted": "Upvoted", - "downvoters": "Downvoters", - "downvoted": "Downvoted", + "upvoters": "Głosujący za", + "upvoted": "Oddane głosy za", + "downvoters": "Głosujący przeciw", + "downvoted": "Oddane głosy przeciw", "views": "wyświetleń", "reputation": "Punkty reputacji", "read_more": "czytaj więcej", diff --git a/public/language/pl/login.json b/public/language/pl/login.json index 2421563634..1bcd2c3cd5 100644 --- a/public/language/pl/login.json +++ b/public/language/pl/login.json @@ -8,5 +8,5 @@ "failed_login_attempt": "Nie udało się zalogować. Spróbuj ponownie.", "login_successful": "Zostałeś pomyślnie zalogowany.", "dont_have_account": "Nie masz konta?", - "logged-out-due-to-inactivity": "You have been logged out of the Admin Control Panel due to inactivity" + "logged-out-due-to-inactivity": "Zostałeś wylogowany z Panelu Administratora z powodu braku aktywności." } \ No newline at end of file diff --git a/public/language/pl/pages.json b/public/language/pl/pages.json index 9e11cb4c57..d748c3919b 100644 --- a/public/language/pl/pages.json +++ b/public/language/pl/pages.json @@ -12,7 +12,7 @@ "users/sort-posts": "Użytkownicy z największą liczbą postów", "users/sort-reputation": "Użytkownicy z najwyższą reputacją", "users/banned": "Banned Users", - "users/most-flags": "Most flagged users", + "users/most-flags": "Najczęściej oznaczani użytkownicy", "users/search": "Wyszukiwanie Użytkownków", "notifications": "Powiadomienia", "tags": "Tagi", @@ -29,7 +29,7 @@ "account/edit/password": "Editing password of \"%1\"", "account/edit/username": "Editing username of \"%1\"", "account/edit/email": "Editing email of \"%1\"", - "account/info": "Account Info", + "account/info": "Informacje o koncie", "account/following": "Obserwowani przez %1", "account/followers": "Obserwujący %1", "account/posts": "Posty napisane przez %1", diff --git a/public/language/pl/register.json b/public/language/pl/register.json index fee052540f..49c89fb6ac 100644 --- a/public/language/pl/register.json +++ b/public/language/pl/register.json @@ -1,6 +1,6 @@ { "register": "Rejestracja", - "cancel_registration": "Cancel Registration", + "cancel_registration": "Anuluj rejestrację", "help.email": "Domyślnie twój adres e-mail będzie ukryty.", "help.username_restrictions": "Unikalna nazwa użytkownika z min. %1 i maks. %2 znaków. Inni użytkownicy mogą ciebie zawołać pisząc @nazwa użytkownika.", "help.minimum_password_length": "Hasło musi mieć co najmniej %1 znaków.", @@ -16,8 +16,8 @@ "alternative_registration": "Alternatywna rejestracja", "terms_of_use": "Warunki korzystania z serwisu", "agree_to_terms_of_use": "Zgadzam się na powyższe warunki", - "terms_of_use_error": "You must agree to the Terms of Use", + "terms_of_use_error": "Musisz zaakceptować Terms of Use", "registration-added-to-queue": "Twoja rejestracja została dodana do kolejki oczekujących na akceptację. Otrzymasz email, kiedy zostanie zatwierdzona przez administratora.", - "interstitial.intro": "We require some additional information before we can create your account.", - "interstitial.errors-found": "We could not complete your registration:" + "interstitial.intro": "Potrzebujemy dodatkowych informacji zanim przejdziemy dalej do utworzenia Twojego konta.", + "interstitial.errors-found": "Nie mogliśmy ukończyć procesu rejestracji:" } \ No newline at end of file diff --git a/public/language/pl/topic.json b/public/language/pl/topic.json index 8c6ed0d56b..c74aa085be 100644 --- a/public/language/pl/topic.json +++ b/public/language/pl/topic.json @@ -26,14 +26,14 @@ "tools": "Narzędzia", "flag": "Zgłoś", "locked": "Zablokowany", - "pinned": "Pinned", - "moved": "Moved", + "pinned": "Przypięte", + "moved": "Przeniesione", "bookmark_instructions": "Click here to return to the last read post in this thread.", "flag_title": "Zgłoś post do moderacji", "flag_success": "Ten post został oznaczony do moderacji.", "deleted_message": "Ten temat został skasowany. Tylko użytkownicy z uprawnieniami do zarządzania mogą go zobaczyć.", "following_topic.message": "Będziesz od teraz otrzymywał powiadomienia, gdy ktoś odpowie w tym temacie.", - "not_following_topic.message": "You will see this topic in the unread topics list, but you will not receive notifications when somebody posts to this topic.", + "not_following_topic.message": "Zobaczysz ten temat na liście nieprzeczytanych, ale nie otrzymasz żadnego powiadomienia dotyczącego tego tematu.", "ignoring_topic.message": "Nie zobaczysz już tego tematu na liście nieprzeczytanych. Otrzymasz powiadomienie, kiedy zostaniesz wspomniany lub ktoś odda głos na twój post.", "login_to_subscribe": "Zaloguj się, aby subskrybować ten temat.", "markAsUnreadForAll.success": "Temat oznaczony jako nieprzeczytany dla wszystkich.", @@ -60,7 +60,7 @@ "thread_tools.move_all": "Przenieś wszystko", "thread_tools.fork": "Skopiuj Temat", "thread_tools.delete": "Usuń Temat", - "thread_tools.delete-posts": "Delete Posts", + "thread_tools.delete-posts": "Usuń posty", "thread_tools.delete_confirm": "Na pewno chcesz skasować ten temat?", "thread_tools.restore": "Przywróć Temat", "thread_tools.restore_confirm": "Na pewno chcesz przywrócić ten temat?", @@ -86,7 +86,7 @@ "topic_will_be_moved_to": "Ten temat zostanie przeniesiony do kategorii", "fork_topic_instruction": "Zaznacz posty, które chcesz sklonować", "fork_no_pids": "Nie zaznaczyłeś żadnych postów!", - "fork_pid_count": "%1 post(s) selected", + "fork_pid_count": "wybrano %1 post(-ów)", "fork_success": "Udało się skopiować temat. Kliknij tutaj, aby do niego przejść.", "delete_posts_instruction": "Kliknij na posty, które chcesz usunąć", "composer.title_placeholder": "Wpisz tutaj tytuł tematu...", @@ -118,5 +118,5 @@ "link_back": "Re: [%1](%2)", "spam": "Spam", "offensive": "Obrażliwy", - "custom-flag-reason": "Enter a flagging reason" + "custom-flag-reason": "Wprowadź powód oznaczenia" } \ No newline at end of file diff --git a/public/language/pl/user.json b/public/language/pl/user.json index 807f9b6bd4..5bc57dafba 100644 --- a/public/language/pl/user.json +++ b/public/language/pl/user.json @@ -6,7 +6,7 @@ "postcount": "Liczba postów", "email": "Adres e-mail", "confirm_email": "Potwierdź e-mail", - "account_info": "Account Info", + "account_info": "Informacje o koncie", "ban_account": "Zbanuj Konto", "ban_account_confirm": "Na pewno chcesz zbanować tego użytkownika?", "unban_account": "Odbanuj Konto", @@ -96,8 +96,8 @@ "delay_image_loading": "Opóźnienie ładowania zdjęcia", "image_load_delay_help": "Jeśli włączone, zdjęcia w temacie nie załadują się dopóki nie najedzie się", "scroll_to_my_post": "Po napisaniu odpowiedzi, wyświetl najnowsze posty", - "follow_topics_you_reply_to": "Watch topics that you reply to", - "follow_topics_you_create": "Watch topics you create", + "follow_topics_you_reply_to": "Obserwuj tematy w których uczestniczysz", + "follow_topics_you_create": "Obserwuj tematy które utworzyłeś", "grouptitle": "Tytuł grupy", "no-group-title": "Brak tytułu grupy", "select-skin": "Wybierz Skórkę", diff --git a/public/language/pt_BR/error.json b/public/language/pt_BR/error.json index eeca061a70..849a4878a1 100644 --- a/public/language/pt_BR/error.json +++ b/public/language/pt_BR/error.json @@ -20,6 +20,7 @@ "email-taken": "Email já cadastrado", "email-not-confirmed": "O seu email ainda não foi confirmado, por favor clique aqui para confirmar seu email.", "email-not-confirmed-chat": "Você não está habilitado a conversar até que seu email seja confirmado, por favor clique aqui para confirmar seu email.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "Este fórum exige confirmação de email, por gentileza clique aqui para digitar um email", "email-confirm-failed": "Nós não pudemos confirmar seu email, por gentileza tente novamente mais tarde.", "confirm-email-already-sent": "O email de confirmação já foi enviado, por favor aguarde %1 minuto(s) para enviar outro.", diff --git a/public/language/ro/error.json b/public/language/ro/error.json index 0dabe24cbf..fdb92e303b 100644 --- a/public/language/ro/error.json +++ b/public/language/ro/error.json @@ -20,6 +20,7 @@ "email-taken": "Adresa de email este deja folostă", "email-not-confirmed": "Adresa ta de email nu a fost inca confirmata, click aici ca sa o confirmi.", "email-not-confirmed-chat": "Nu vei putea trimite mesaje daca email-ul tau nu e confirmat, click aici sa il confirmi.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "Ca sa accesezi forumul trebuie sa iti confirmi email-ul, click aici ca sa intri in mail.", "email-confirm-failed": "Mail-ul tau nu a putut fi confirmat, te rog incearca mai tarziu.", "confirm-email-already-sent": "Email-ul de confirmare ti-a fost trimis, asteapta te rog %1 minut(e) ca sa trimiti inca unul.", diff --git a/public/language/ru/error.json b/public/language/ru/error.json index 80f601eb1e..a0e7ea3108 100644 --- a/public/language/ru/error.json +++ b/public/language/ru/error.json @@ -20,6 +20,7 @@ "email-taken": "Email занят", "email-not-confirmed": "Ваш email не подтвержден, нажмите для подтверждения.", "email-not-confirmed-chat": "Вы не можете оставлять сообщения, пока Ваш email не подтверждён. Нажмите на это сообщение чтобы получить письмо повторно.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "Этот форум требует подтверждения по E-mail. Нажмите здесь для ввода E-mail.", "email-confirm-failed": "Мы не можем подтвердить Ваш E-mail, попробуйте позже.", "confirm-email-already-sent": "Сообщение для подтверждения уже выслано на E-mail. Повторная отправка возможна через %1 мин.", diff --git a/public/language/rw/error.json b/public/language/rw/error.json index abe75583d8..07e0a50743 100644 --- a/public/language/rw/error.json +++ b/public/language/rw/error.json @@ -20,6 +20,7 @@ "email-taken": "Email yarafashwe mbere", "email-not-confirmed": "Email yawe ntabwo iremezwa. Kanda hano kugirango wemeze email yawe.", "email-not-confirmed-chat": "Ntabwo uremererwa kuganirira mu gikari kuko email yawe itari yemezwa. Kanda hano kugirango wemeze email yawe. ", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "Uru rubuga rusaba ko wemeza ko utunze email. Kanda hano kugirango utange email yawe", "email-confirm-failed": "Ntabwo email yawe yabashije kwemezwa. Ongera ugerageze mu bundi buryo. ", "confirm-email-already-sent": "Email yo kwemeza yamaze koherezwa. Tegereza iminota (umunota) %1 mbere yo kohereza indi. ", diff --git a/public/language/sc/error.json b/public/language/sc/error.json index 3a95ab7cc6..6a614b6de4 100644 --- a/public/language/sc/error.json +++ b/public/language/sc/error.json @@ -20,6 +20,7 @@ "email-taken": "Email taken", "email-not-confirmed": "Your email has not been confirmed yet, please click here to confirm your email.", "email-not-confirmed-chat": "You are unable to chat until your email is confirmed, please click here to confirm your email.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "This forum requires email confirmation, please click here to enter an email", "email-confirm-failed": "We could not confirm your email, please try again later.", "confirm-email-already-sent": "Confirmation email already sent, please wait %1 minute(s) to send another one.", diff --git a/public/language/sk/error.json b/public/language/sk/error.json index 8d286eaa7c..d5116a21d9 100644 --- a/public/language/sk/error.json +++ b/public/language/sk/error.json @@ -20,6 +20,7 @@ "email-taken": "Email je obsadený", "email-not-confirmed": "Your email has not been confirmed yet, please click here to confirm your email.", "email-not-confirmed-chat": "You are unable to chat until your email is confirmed, please click here to confirm your email.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "This forum requires email confirmation, please click here to enter an email", "email-confirm-failed": "We could not confirm your email, please try again later.", "confirm-email-already-sent": "Confirmation email already sent, please wait %1 minute(s) to send another one.", diff --git a/public/language/sl/error.json b/public/language/sl/error.json index aa23d38025..709870ec9c 100644 --- a/public/language/sl/error.json +++ b/public/language/sl/error.json @@ -20,6 +20,7 @@ "email-taken": "E-mail naslov je že zaseden", "email-not-confirmed": "Vaš e-mail naslov še ni bil potrjen. Prosimo kliknite tu za potrditev vašega e-mail naslova.", "email-not-confirmed-chat": "Ne morete klepetati dokler ne potrdite vašega e-mail naslova. Prosimo kliknite tu za potrditev vašega e-mail naslova.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "Ta forum zahteva potrjen e-mail naslov. Prosim kliknite tu za vnos e-mail naslova.", "email-confirm-failed": "Nismo mogli potrditi vašega e-mail naslova. Prosimo poskusite ponovno.", "confirm-email-already-sent": "Potrditveni e-mail naslov je že poslan. Prosimo počakajte %1 minut(o) za ponovno pošiljanje.", diff --git a/public/language/sr/error.json b/public/language/sr/error.json index 3827af2da1..05241438be 100644 --- a/public/language/sr/error.json +++ b/public/language/sr/error.json @@ -20,6 +20,7 @@ "email-taken": "Адреса е-поште је заусета", "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.", "no-email-to-confirm": "Форум захтева потврду е-поште, кликните овде да бисте отворили е-пошту", "email-confirm-failed": "Потврда е-поште није успела, молимо вас да покушате касније.", "confirm-email-already-sent": "Конфирмациони имејл је већ послат, молимо вас да сачекате %1 минут(а) да бисте послали други.", diff --git a/public/language/sv/error.json b/public/language/sv/error.json index 9096296fbb..172f78e6cd 100644 --- a/public/language/sv/error.json +++ b/public/language/sv/error.json @@ -20,6 +20,7 @@ "email-taken": "Epostadress upptagen", "email-not-confirmed": "Din epostadress är ännu inte bekräftad. Klicka här för att bekräfta din epostadress.", "email-not-confirmed-chat": "Du kan ej använda chatten förrän din epostadress har blivit bekräftad, var god klicka här för att bekräfta din epostadress.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "Detta forum kräver bekräftning av epostadresser, var god klicka här för att fylla i en epostadress", "email-confirm-failed": "Vi kunde ej bekräfta din epostadress, var god försök igen senare.", "confirm-email-already-sent": "Bekräftningsbrev redan skickat, var god vänta %1 minut(er) innan du skickar ett nytt.", diff --git a/public/language/th/error.json b/public/language/th/error.json index fcb210f49c..27373e3aa5 100644 --- a/public/language/th/error.json +++ b/public/language/th/error.json @@ -20,6 +20,7 @@ "email-taken": "อีเมลนี้มีการใช้แล้ว", "email-not-confirmed": "ยังไม่มีการยืนยันอีเมลของคุณ, โปรดกดยืนยันอีเมลของคุณตรงนี้", "email-not-confirmed-chat": "You are unable to chat until your email is confirmed, please click here to confirm your email.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "Forum นี้ต้องการการยืนยันอีเมล กรุณากดที่นี่เพื่อระบุอีเมล", "email-confirm-failed": "เราไม่สามารถยืนยันอีเมลของคุณ ณ ขณะนี้ กรุณาลองใหม่อีกครั้งภายหลัง", "confirm-email-already-sent": "Confirmation email already sent, please wait %1 minute(s) to send another one.", diff --git a/public/language/tr/error.json b/public/language/tr/error.json index 6fad971610..27385670ed 100644 --- a/public/language/tr/error.json +++ b/public/language/tr/error.json @@ -20,6 +20,7 @@ "email-taken": "E-posta Alınmış", "email-not-confirmed": "E-postanız onaylanmamış, onaylamak için lütfen buraya tıklayın.", "email-not-confirmed-chat": "E-postanız onaylanana kadar sohbet edemezsiniz, onaylamak için lütfen buraya tıklayın.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "Bu forum e-posta doğrulaması gerektirir, lütfen buraya bir e-posta adresi girin", "email-confirm-failed": "E-posta adresinizi doğrulayamıyoruz. Lütfen daha sonra tekrar deneyin.", "confirm-email-already-sent": "E-mail onayı zaten gönderilmiş, yeni bir onay göndermek için lütfen 1 dakika bekleyin.", diff --git a/public/language/vi/error.json b/public/language/vi/error.json index 38a0ab9a69..6af283b8de 100644 --- a/public/language/vi/error.json +++ b/public/language/vi/error.json @@ -20,6 +20,7 @@ "email-taken": "Email đã được đăng kí", "email-not-confirmed": "Email của bạn chưa được xác nhận, xin hãy nhấn vào đây để xác nhận địa chỉ này là của bạn", "email-not-confirmed-chat": "Bạn không được quyền chat nếu email của bạn chưa được xác nhận, vui lòng click vào đây để xác nhận email của bạn.", + "email-not-confirmed-email-sent": "Email của bạn chưa được xác nhận, xin hãy nhấn vào đây để xác nhận địa chỉ này là của bạn", "no-email-to-confirm": "Diễn đàn này yêu cầu xác nhận email, vui lòng nhấn vào đây để nhập email.", "email-confirm-failed": "Chúng tôi không thể xác nhận email của bạn, vui lòng thử lại sau.", "confirm-email-already-sent": "Email xác nhận đã được gửi, vui lòng chờ %1 phút để yêu cầu gửi lại.", @@ -29,8 +30,8 @@ "password-too-long": "Mật khẩu quá dài", "user-banned": "Tài khoản bị ban", "user-too-new": "Rất tiếc, bạn phải chờ %1 giây để đăng bài viết đầu tiên.", - "blacklisted-ip": "Rất tiếc, địa chỉ IP của bạn đã bị ban khỏi cộng đồng. Nếu bạn cảm thấy có gì không đúng, hãy liên lạc với người quản trị.", - "ban-expiry-missing": "Please provide an end date for this ban", + "blacklisted-ip": "Rất tiếc, địa chỉ IP của bạn đã bị cấm khỏi cộng đồng. Nếu bạn cảm thấy có gì không đúng, hãy liên lạc với người quản trị.", + "ban-expiry-missing": "Vui lòng cung cấp ngày hết hạn của lệnh cấm", "no-category": "Danh mục không tồn tại", "no-topic": "Chủ đề không tồn tại", "no-post": "Bài viết không tồn tại", @@ -47,13 +48,13 @@ "post-edit-duration-expired-hours-minutes": "Bạn chỉ được phép sửa các bài viết sau khi đăng %1 giờ(s) %2 phút(s)", "post-edit-duration-expired-days": "Bạn chỉ được phép sửa các bài viết sau khi đăng %1 ngày(s)", "post-edit-duration-expired-days-hours": "Bạn chỉ được phép sửa các bài viết sau khi đăng %1 ngày(s) %2 giờ(s)", - "post-delete-duration-expired": "You are only allowed to delete posts for %1 second(s) after posting", - "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-days-hours": "You are only allowed to delete posts for %1 day(s) %2 hour(s) after posting", + "post-delete-duration-expired": "Bạn chỉ được phép xóa bài viết sau khi đăng %1 giây(s)", + "post-delete-duration-expired-minutes": "Bạn chỉ được phép xóa bài viết sau khi đăng %1 phút(s)", + "post-delete-duration-expired-minutes-seconds": "Bạn chỉ được phép xóa các bài viết sau khi đăng %1 phút(s) %2 giây(s)", + "post-delete-duration-expired-hours": "Bạn chỉ được phép xóa bài viết sau khi đăng %1 giờ(s)", + "post-delete-duration-expired-hours-minutes": "Bạn chỉ được phép xóa bài viết sau khi đăng %1 giờ(s) 2 phút(s)", + "post-delete-duration-expired-days": "Bạn chỉ được phép xóa các bài viết sau khi đăng %1 ngày(s)", + "post-delete-duration-expired-days-hours": "Bạn chỉ được phép xóa các bài viết sau khi đăng %1 ngày(s) %2 giờ(s)", "content-too-short": "Vui lòng nhập một bài viết dài hơn. Bài viết phải có tối thiểu %1 ký tự.", "content-too-long": "Vui lòng nhập một bài viết ngắn hơn. Bài viết chỉ có thể có tối đa %1 ký tự.", "title-too-short": "Vui lòng nhập tiêu đề dài hơn. Tiêu đề phải có tối thiểu %1 ký tự.", @@ -69,14 +70,14 @@ "guest-upload-disabled": "Khách (chưa có tài khoản) không có quyền tải lên file.", "already-favourited": "Bạn đã đánh dấu bài viết này", "already-unfavourited": "Bạn đã bỏ đánh dấu bài viết này", - "cant-ban-other-admins": "Bạn không thể ban được các admin khác", + "cant-ban-other-admins": "Bạn không thể cấm được các quản trị viên khác", "cant-remove-last-admin": "Bạn là quản trị viên duy nhất. Hãy cho thành viên khác làm quản trị viên trước khi huỷ bỏ quyền quản trị của bạn.", - "cant-delete-admin": "Remove administrator privileges from this account before attempting to delete it.", + "cant-delete-admin": "Hủy quyền quản trị của tài khoản này trước khi xóa", "invalid-image-type": "Định dạng ảnh không hợp lệ. Những định dạng được cho phép là: %1", "invalid-image-extension": "Định dạng ảnh không hợp lệ", "invalid-file-type": "Định dạng file không hợp lệ. Những định dạng được cho phép là: %1", "group-name-too-short": "Tên nhóm quá ngắn", - "group-name-too-long": "Group name too long", + "group-name-too-long": "Tên nhóm quá dài", "group-already-exists": "Nhóm đã tồn tại", "group-name-change-not-allowed": "Không cho phép đổi tên nhóm", "group-already-member": "Bạn đã là thành viên của nhóm này.", @@ -119,6 +120,6 @@ "not-in-room": "Thành viên không có trong phòng", "no-users-in-room": "Không có ai trong phòng này", "cant-kick-self": "Bạn không thể kick chính bạn ra khỏi nhóm", - "no-users-selected": "No user(s) selected", - "invalid-home-page-route": "Invalid home page route" + "no-users-selected": "Chưa có người dùng(s) nào", + "invalid-home-page-route": "Đường dẫn trang chủ không hợp lệ" } \ No newline at end of file diff --git a/public/language/vi/global.json b/public/language/vi/global.json index 7eb329ec13..6928ecfefa 100644 --- a/public/language/vi/global.json +++ b/public/language/vi/global.json @@ -50,9 +50,9 @@ "topics": "Số Chủ đề", "posts": "Số bài viết", "best": "Hay nhất", - "upvoters": "Upvoters", + "upvoters": "Tán thành", "upvoted": "Tán thành", - "downvoters": "Downvoters", + "downvoters": "Phản đối", "downvoted": "Phản đối", "views": "Lượt xem", "reputation": "Điểm tín nhiệm", diff --git a/public/language/vi/topic.json b/public/language/vi/topic.json index 3035b9ac9d..8701518f30 100644 --- a/public/language/vi/topic.json +++ b/public/language/vi/topic.json @@ -26,14 +26,14 @@ "tools": "Công cụ", "flag": "Gắn cờ", "locked": "Khóa", - "pinned": "Pinned", - "moved": "Moved", + "pinned": "Đã ghim", + "moved": "Chuyển đi", "bookmark_instructions": "Bấm vào đây để quay về đọc bài viết mới nhất trong chủ đề này.", "flag_title": "Flag bài viết này để chỉnh sửa", "flag_success": "Chủ đề này đã được flag để chỉnh sửa", "deleted_message": "Chủ đề này đã bị xóa. Chỉ ban quản trị mới xem được.", "following_topic.message": "Từ giờ bạn sẽ nhận được thông báo khi có ai đó gửi bài viết trong chủ đề này", - "not_following_topic.message": "You will see this topic in the unread topics list, but you will not receive notifications when somebody posts to this topic.", + "not_following_topic.message": "Bạn có thể xem chủ đề này trong danh sách chủ đề chưa xem, nhưng bạn sẽ không nhận thông báo khi có ai đó đăng bài viết trong chủ đề này", "ignoring_topic.message": "Bạn sẽ không còn xem được chủ đề này trong danh sách các chủ đề chưa đọc nữa. Bạn sẽ nhận được thông báo khi bạn được đề cập tới hoặc bài viết của bạn được bỏ phiếu.", "login_to_subscribe": "Xin hãy đăng ký hoặc đăng nhập để theo dõi topic này", "markAsUnreadForAll.success": "Chủ đề đã được đánh dấu là chưa đọc toàn bộ", @@ -86,7 +86,7 @@ "topic_will_be_moved_to": "Chủ đề này sẽ được chuyển tới phần mục", "fork_topic_instruction": "Chọn vào bài gửi mà bạn muốn fork", "fork_no_pids": "Chưa chọn bài gửi nào!", - "fork_pid_count": "%1 post(s) selected", + "fork_pid_count": "%1 bài viết(s) đã được gửi", "fork_success": "Tạo bản sao thành công! Nhấn vào đây để chuyển tới chủ đề vừa tạo.", "delete_posts_instruction": "Chọn những bài viết bạn muốn xoá", "composer.title_placeholder": "Nhập tiêu đề cho chủ đề của bạn tại đây...", diff --git a/public/language/zh_CN/error.json b/public/language/zh_CN/error.json index 51ce4481b2..aa496cca6f 100644 --- a/public/language/zh_CN/error.json +++ b/public/language/zh_CN/error.json @@ -20,6 +20,7 @@ "email-taken": "此电子邮箱已被占用", "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.", "no-email-to-confirm": "本论坛需要电子邮箱确认,请点击这里输入电子邮箱地址", "email-confirm-failed": "我们无法确认您的电子邮箱,请重试", "confirm-email-already-sent": "确认邮件已发出,如需重新发送请等待 %1 分钟后再试。", diff --git a/public/language/zh_TW/error.json b/public/language/zh_TW/error.json index 617902283b..3c9a9849e6 100644 --- a/public/language/zh_TW/error.json +++ b/public/language/zh_TW/error.json @@ -20,6 +20,7 @@ "email-taken": "該信箱已被使用", "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.", "no-email-to-confirm": "討論區要求電子郵件確認,請點擊這裡輸入一個電子郵件。", "email-confirm-failed": "我們無法確認你的Email,請之後再重試。", "confirm-email-already-sent": "確認電子郵件已經寄送,請等待 %1 分鐘才能再寄送另一封。", From bc961e21575bcf5ba2eb17a1a248a4ae78bea26e Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Thu, 11 Aug 2016 16:43:38 -0400 Subject: [PATCH 29/63] removing reload, closes #4936, closes #4929 --- src/controllers/admin/dashboard.js | 4 +-- src/meta.js | 46 +++------------------------ src/meta/themes.js | 2 -- src/socket.io/admin.js | 19 +++-------- src/views/admin/general/dashboard.tpl | 5 ++- src/views/admin/partials/menu.tpl | 5 --- src/views/admin/settings/advanced.tpl | 4 +-- 7 files changed, 15 insertions(+), 70 deletions(-) diff --git a/src/controllers/admin/dashboard.js b/src/controllers/admin/dashboard.js index 24a65983f1..84ee4fd3d0 100644 --- a/src/controllers/admin/dashboard.js +++ b/src/controllers/admin/dashboard.js @@ -19,8 +19,8 @@ dashboardController.get = function(req, res, next) { var notices = [ { done: !meta.reloadRequired, - doneText: 'Reload not required', - notDoneText:'Reload required' + doneText: 'Restart not required', + notDoneText:'Restart required' }, { done: plugins.hasListeners('filter:search.query'), diff --git a/src/meta.js b/src/meta.js index 1cbd1af0ae..8dfbc0d99a 100644 --- a/src/meta.js +++ b/src/meta.js @@ -41,50 +41,14 @@ var async = require('async'), }); }; + /** + * Reload deprecated as of v1.1.2+, remove in v2.x + */ Meta.reload = function(callback) { - pubsub.publish('meta:reload', {hostname: os.hostname()}); - reload(callback); + restart(); + callback(); }; - pubsub.on('meta:reload', function(data) { - if (data.hostname !== os.hostname()) { - reload(); - } - }); - - function reload(callback) { - callback = callback || function() {}; - - var plugins = require('./plugins'); - async.series([ - function (next) { - plugins.fireHook('static:app.reload', {}, next); - }, - async.apply(plugins.clearRequireCache), - async.apply(Meta.css.minify), - async.apply(Meta.js.minify, 'nodebb.min.js'), - async.apply(Meta.js.minify, 'acp.min.js'), - async.apply(Meta.sounds.init), - async.apply(languages.init), - async.apply(Meta.templates.compile), - async.apply(plugins.reload), - async.apply(plugins.reloadRoutes), - async.apply(auth.reloadRoutes), - function(next) { - Meta.config['cache-buster'] = utils.generateUUID(); - templates.flush(); - next(); - } - ], function(err) { - if (!err) { - emitter.emit('nodebb:ready'); - } - Meta.reloadRequired = false; - - callback(err); - }); - } - Meta.restart = function() { pubsub.publish('meta:restart', {hostname: os.hostname()}); restart(); diff --git a/src/meta/themes.js b/src/meta/themes.js index c3d912a222..ed6b061db9 100644 --- a/src/meta/themes.js +++ b/src/meta/themes.js @@ -161,6 +161,4 @@ module.exports = function(Meta) { nconf.set('theme_templates_path', themePath); nconf.set('theme_config', path.join(nconf.get('themes_path'), themeObj.id, 'theme.json')); }; - - }; \ No newline at end of file diff --git a/src/socket.io/admin.js b/src/socket.io/admin.js index a290238e21..556eee0290 100644 --- a/src/socket.io/admin.js +++ b/src/socket.io/admin.js @@ -49,21 +49,10 @@ SocketAdmin.before = function(socket, method, data, next) { }); }; -SocketAdmin.reload = function(socket, data, callback) { - events.log({ - type: 'reload', - uid: socket.uid, - ip: socket.ip - }); - if (process.send) { - process.send({ - action: 'reload' - }); - callback(); - } else { - meta.reload(callback); - } -}; +/** + * Reload deprecated as of v1.1.2+, remove in v2.x + */ +SocketAdmin.reload = SocketAdmin.restart; SocketAdmin.restart = function(socket, data, callback) { events.log({ diff --git a/src/views/admin/general/dashboard.tpl b/src/views/admin/general/dashboard.tpl index 6ea841352a..a478c21c16 100644 --- a/src/views/admin/general/dashboard.tpl +++ b/src/views/admin/general/dashboard.tpl @@ -95,11 +95,10 @@
    System Control
    @@ -96,7 +96,7 @@

    Lowering this value causes NodeBB to become more sensitive to spikes in load, but - may also cause the check to become too sensitive. (Reload required) + may also cause the check to become too sensitive. (Restart required)

    From 606712849358d4effa276ff9ea3d1c72b2213529 Mon Sep 17 00:00:00 2001 From: NodeBB Misty Date: Thu, 11 Aug 2016 17:07:15 -0400 Subject: [PATCH 30/63] Latest translations and fallbacks --- public/language/ar/modules.json | 1 + public/language/bg/modules.json | 1 + public/language/bn/modules.json | 1 + public/language/cs/modules.json | 1 + public/language/da/modules.json | 1 + public/language/de/modules.json | 1 + public/language/el/modules.json | 1 + public/language/en@pirate/modules.json | 1 + public/language/en_US/modules.json | 1 + public/language/es/category.json | 2 +- public/language/es/modules.json | 1 + public/language/et/modules.json | 1 + public/language/fa_IR/modules.json | 1 + public/language/fi/modules.json | 1 + public/language/fr/modules.json | 1 + public/language/gl/modules.json | 1 + public/language/he/modules.json | 1 + public/language/hu/modules.json | 1 + public/language/id/modules.json | 1 + public/language/it/modules.json | 1 + public/language/ja/modules.json | 1 + public/language/ko/modules.json | 1 + public/language/lt/modules.json | 1 + public/language/ms/modules.json | 1 + public/language/nb/modules.json | 1 + public/language/nl/modules.json | 1 + public/language/pl/modules.json | 1 + public/language/pt_BR/modules.json | 1 + public/language/ro/modules.json | 1 + public/language/ru/modules.json | 1 + public/language/rw/modules.json | 1 + public/language/sc/modules.json | 1 + public/language/sk/modules.json | 1 + public/language/sl/modules.json | 1 + public/language/sr/modules.json | 1 + public/language/sv/modules.json | 1 + public/language/th/modules.json | 1 + public/language/tr/modules.json | 1 + public/language/vi/modules.json | 1 + public/language/zh_CN/modules.json | 1 + public/language/zh_TW/modules.json | 1 + 41 files changed, 41 insertions(+), 1 deletion(-) diff --git a/public/language/ar/modules.json b/public/language/ar/modules.json index c753143075..ce14cc171b 100644 --- a/public/language/ar/modules.json +++ b/public/language/ar/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "إلغاء", "bootbox.confirm": "تأكيد", diff --git a/public/language/bg/modules.json b/public/language/bg/modules.json index d87e0f446d..c9cee68f96 100644 --- a/public/language/bg/modules.json +++ b/public/language/bg/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Снимка", "composer.upload-picture": "Качване на изображение", "composer.upload-file": "Качване на файл", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "Добре", "bootbox.cancel": "Отказ", "bootbox.confirm": "Потвърждаване", diff --git a/public/language/bn/modules.json b/public/language/bn/modules.json index 567a648df0..67a8aeddd3 100644 --- a/public/language/bn/modules.json +++ b/public/language/bn/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Cancel", "bootbox.confirm": "Confirm", diff --git a/public/language/cs/modules.json b/public/language/cs/modules.json index a6d59b761f..d12f123cb1 100644 --- a/public/language/cs/modules.json +++ b/public/language/cs/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Obrázek", "composer.upload-picture": "Nahrát obrázek", "composer.upload-file": "Nahrát soubor", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Zrušit", "bootbox.confirm": "Potvrdit", diff --git a/public/language/da/modules.json b/public/language/da/modules.json index d54ad1ec52..01a3655865 100644 --- a/public/language/da/modules.json +++ b/public/language/da/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Annuller", "bootbox.confirm": "Bekræft", diff --git a/public/language/de/modules.json b/public/language/de/modules.json index e5f569dbed..688564237f 100644 --- a/public/language/de/modules.json +++ b/public/language/de/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Bild", "composer.upload-picture": "Bild hochladen", "composer.upload-file": "Datei hochladen", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Abbrechen", "bootbox.confirm": "Bestätigen", diff --git a/public/language/el/modules.json b/public/language/el/modules.json index af0d74e3cd..2103f5def7 100644 --- a/public/language/el/modules.json +++ b/public/language/el/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Cancel", "bootbox.confirm": "Confirm", diff --git a/public/language/en@pirate/modules.json b/public/language/en@pirate/modules.json index 974cdf1b43..aca98482b4 100644 --- a/public/language/en@pirate/modules.json +++ b/public/language/en@pirate/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Cancel", "bootbox.confirm": "Confirm", diff --git a/public/language/en_US/modules.json b/public/language/en_US/modules.json index b3775ab68f..ac0177941a 100644 --- a/public/language/en_US/modules.json +++ b/public/language/en_US/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Cancel", "bootbox.confirm": "Confirm", diff --git a/public/language/es/category.json b/public/language/es/category.json index 4ae8ebc1e6..1997061dea 100644 --- a/public/language/es/category.json +++ b/public/language/es/category.json @@ -2,7 +2,7 @@ "category": "Categoría", "subcategories": "Subcategorías", "new_topic_button": "Nuevo tema", - "guest-login-post": "Accede para poder escribir un mensaje", + "guest-login-post": "Accede para escribir un mensaje", "no_topics": "No hay temas en esta categoría.
    ¿Por qué no te animas y publicas uno?", "browsing": "viendo ahora", "no_replies": "Nadie ha respondido aún", diff --git a/public/language/es/modules.json b/public/language/es/modules.json index 87cc59c2fb..d47569a921 100644 --- a/public/language/es/modules.json +++ b/public/language/es/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Foto", "composer.upload-picture": "Subir foto", "composer.upload-file": "Subir archivo", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Cancelar", "bootbox.confirm": "Confirmar", diff --git a/public/language/et/modules.json b/public/language/et/modules.json index c4a2434ec1..bb0f15c66a 100644 --- a/public/language/et/modules.json +++ b/public/language/et/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Pilt", "composer.upload-picture": "Lae pilt üles", "composer.upload-file": "Lae fail üles", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "Olgu", "bootbox.cancel": "Katkesta", "bootbox.confirm": "Kinnita", diff --git a/public/language/fa_IR/modules.json b/public/language/fa_IR/modules.json index 728ffe5153..20f1a0d8d1 100644 --- a/public/language/fa_IR/modules.json +++ b/public/language/fa_IR/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "عکس", "composer.upload-picture": "بارگذاری عکس", "composer.upload-file": "بارگذاری فایل", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "باشه", "bootbox.cancel": "انصراف", "bootbox.confirm": "تایید", diff --git a/public/language/fi/modules.json b/public/language/fi/modules.json index 77fff03fd5..bc7af01bb1 100644 --- a/public/language/fi/modules.json +++ b/public/language/fi/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Cancel", "bootbox.confirm": "Confirm", diff --git a/public/language/fr/modules.json b/public/language/fr/modules.json index bc05644724..09746bc86b 100644 --- a/public/language/fr/modules.json +++ b/public/language/fr/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Image", "composer.upload-picture": "Envoyer une image", "composer.upload-file": "Envoyer un fichier", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Annuler", "bootbox.confirm": "Confirmer", diff --git a/public/language/gl/modules.json b/public/language/gl/modules.json index d097d97686..9bebb20db3 100644 --- a/public/language/gl/modules.json +++ b/public/language/gl/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Foto", "composer.upload-picture": "Subir foto", "composer.upload-file": "Subir arquivo", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "De acordo", "bootbox.cancel": "Cancelar", "bootbox.confirm": "Confirmar", diff --git a/public/language/he/modules.json b/public/language/he/modules.json index 3664bac5b3..91827e7141 100644 --- a/public/language/he/modules.json +++ b/public/language/he/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "בסדר", "bootbox.cancel": "בטל", "bootbox.confirm": "אשר", diff --git a/public/language/hu/modules.json b/public/language/hu/modules.json index e7262c7dff..cd01a6c35f 100644 --- a/public/language/hu/modules.json +++ b/public/language/hu/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Cancel", "bootbox.confirm": "Confirm", diff --git a/public/language/id/modules.json b/public/language/id/modules.json index bd2946c9d7..e56070fdd4 100644 --- a/public/language/id/modules.json +++ b/public/language/id/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Cancel", "bootbox.confirm": "Confirm", diff --git a/public/language/it/modules.json b/public/language/it/modules.json index 1d39879d23..d18485ef7d 100644 --- a/public/language/it/modules.json +++ b/public/language/it/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Annulla", "bootbox.confirm": "Conferma", diff --git a/public/language/ja/modules.json b/public/language/ja/modules.json index bc661721f9..0eb13821d6 100644 --- a/public/language/ja/modules.json +++ b/public/language/ja/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Cancel", "bootbox.confirm": "Confirm", diff --git a/public/language/ko/modules.json b/public/language/ko/modules.json index 3d7b19c6a1..1a4cfa7b1c 100644 --- a/public/language/ko/modules.json +++ b/public/language/ko/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "확인", "bootbox.cancel": "취소", "bootbox.confirm": "확인", diff --git a/public/language/lt/modules.json b/public/language/lt/modules.json index a490086245..a339fe7558 100644 --- a/public/language/lt/modules.json +++ b/public/language/lt/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Cancel", "bootbox.confirm": "Confirm", diff --git a/public/language/ms/modules.json b/public/language/ms/modules.json index 774d674123..15c7f29f9f 100644 --- a/public/language/ms/modules.json +++ b/public/language/ms/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "Ok", "bootbox.cancel": "Batal", "bootbox.confirm": "Pasti", diff --git a/public/language/nb/modules.json b/public/language/nb/modules.json index 6b3309287d..999358e96c 100644 --- a/public/language/nb/modules.json +++ b/public/language/nb/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Avbryt", "bootbox.confirm": "Bekreft", diff --git a/public/language/nl/modules.json b/public/language/nl/modules.json index 9210bfd177..5d27c1549f 100644 --- a/public/language/nl/modules.json +++ b/public/language/nl/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Afbeelding", "composer.upload-picture": "Upload afbeelding", "composer.upload-file": "Upload bestand", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Annuleren", "bootbox.confirm": "Bevestig", diff --git a/public/language/pl/modules.json b/public/language/pl/modules.json index 1a9902604b..5461f81b39 100644 --- a/public/language/pl/modules.json +++ b/public/language/pl/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Obraz", "composer.upload-picture": "Wyślij obraz", "composer.upload-file": "Wyślij plik", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Anuluj", "bootbox.confirm": "Potwierdź", diff --git a/public/language/pt_BR/modules.json b/public/language/pt_BR/modules.json index 20d1fe1805..d9c8e1653d 100644 --- a/public/language/pt_BR/modules.json +++ b/public/language/pt_BR/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Imagem", "composer.upload-picture": "Fazer upload de Imagem", "composer.upload-file": "Fazer upload de Arquivo", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Cancelar", "bootbox.confirm": "Confirmar", diff --git a/public/language/ro/modules.json b/public/language/ro/modules.json index fa79140b83..1c25e2a5ba 100644 --- a/public/language/ro/modules.json +++ b/public/language/ro/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Cancel", "bootbox.confirm": "Confirm", diff --git a/public/language/ru/modules.json b/public/language/ru/modules.json index a4dfd79293..17151cbc94 100644 --- a/public/language/ru/modules.json +++ b/public/language/ru/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Изображение", "composer.upload-picture": "Загрузить изображение", "composer.upload-file": "Загрузить файл", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "ОК", "bootbox.cancel": "Отмена", "bootbox.confirm": "Подтвердить", diff --git a/public/language/rw/modules.json b/public/language/rw/modules.json index 15d1ea25eb..2ce5ceac86 100644 --- a/public/language/rw/modules.json +++ b/public/language/rw/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "Sawa", "bootbox.cancel": "Isubire", "bootbox.confirm": "Emeza", diff --git a/public/language/sc/modules.json b/public/language/sc/modules.json index 93c5b11202..9727532086 100644 --- a/public/language/sc/modules.json +++ b/public/language/sc/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Cancel", "bootbox.confirm": "Confirm", diff --git a/public/language/sk/modules.json b/public/language/sk/modules.json index 0268001e7f..b7450e202c 100644 --- a/public/language/sk/modules.json +++ b/public/language/sk/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Cancel", "bootbox.confirm": "Confirm", diff --git a/public/language/sl/modules.json b/public/language/sl/modules.json index a9b88e3019..34b250169e 100644 --- a/public/language/sl/modules.json +++ b/public/language/sl/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "Vredu", "bootbox.cancel": "Prekliči", "bootbox.confirm": "Potrdi", diff --git a/public/language/sr/modules.json b/public/language/sr/modules.json index 24d2e521f9..2ef142c34f 100644 --- a/public/language/sr/modules.json +++ b/public/language/sr/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "ОК", "bootbox.cancel": "Откажи", "bootbox.confirm": "Потврди", diff --git a/public/language/sv/modules.json b/public/language/sv/modules.json index 3d69a7aab8..56ddf0ceb5 100644 --- a/public/language/sv/modules.json +++ b/public/language/sv/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Bild", "composer.upload-picture": "Ladda upp bild", "composer.upload-file": "Ladda upp fil", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Avbryt", "bootbox.confirm": "Bekräfta", diff --git a/public/language/th/modules.json b/public/language/th/modules.json index 51c6065cd8..2527f30e40 100644 --- a/public/language/th/modules.json +++ b/public/language/th/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Cancel", "bootbox.confirm": "Confirm", diff --git a/public/language/tr/modules.json b/public/language/tr/modules.json index 06e5876c68..059d8670fb 100644 --- a/public/language/tr/modules.json +++ b/public/language/tr/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Görsel", "composer.upload-picture": "Görsel Yükle", "composer.upload-file": "Dosya Yükle", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "Tamam", "bootbox.cancel": "İptal", "bootbox.confirm": "Onayla", diff --git a/public/language/vi/modules.json b/public/language/vi/modules.json index c7863e97aa..fda573b3fd 100644 --- a/public/language/vi/modules.json +++ b/public/language/vi/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Hình ảnh", "composer.upload-picture": "Tải ảnh lên", "composer.upload-file": "Tải file lên", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Huỷ bỏ", "bootbox.confirm": "Xác nhận", diff --git a/public/language/zh_CN/modules.json b/public/language/zh_CN/modules.json index da6d813ee3..869a8bf0c0 100644 --- a/public/language/zh_CN/modules.json +++ b/public/language/zh_CN/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "图片", "composer.upload-picture": "上传图片", "composer.upload-file": "上传文件", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "确认", "bootbox.cancel": "取消", "bootbox.confirm": "确认", diff --git a/public/language/zh_TW/modules.json b/public/language/zh_TW/modules.json index bbf71c78bf..e02c0908f1 100644 --- a/public/language/zh_TW/modules.json +++ b/public/language/zh_TW/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "圖片", "composer.upload-picture": "上傳圖片", "composer.upload-file": "上傳檔案", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "好", "bootbox.cancel": "取消", "bootbox.confirm": "確認", From e55043e5abeab6470ed4a862e14ec8c3829b2c13 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Fri, 12 Aug 2016 01:14:01 +0300 Subject: [PATCH 31/63] closes #4867 --- install/web.js | 60 ++++++++++++++++----------------- public/src/installer/install.js | 5 ++- src/views/install/index.tpl | 8 ++--- 3 files changed, 38 insertions(+), 35 deletions(-) diff --git a/install/web.js b/install/web.js index 7d2cfad21a..0f4e645e8a 100644 --- a/install/web.js +++ b/install/web.js @@ -1,16 +1,16 @@ "use strict"; -var winston = require('winston'), - express = require('express'), - bodyParser = require('body-parser'), - fs = require('fs'), - path = require('path'), - less = require('less'), - async = require('async'), - uglify = require('uglify-js'), - nconf = require('nconf'), - app = express(), - server; +var winston = require('winston'); +var express = require('express'); +var bodyParser = require('body-parser'); +var fs = require('fs'); +var path = require('path'); +var less = require('less'); +var async = require('async'); +var uglify = require('uglify-js'); +var nconf = require('nconf'); +var app = express(); +var server; winston.add(winston.transports.File, { filename: 'logs/webinstall.log', @@ -22,13 +22,13 @@ winston.add(winston.transports.File, { level: 'verbose' }); -var web = {}, - scripts = [ - 'public/vendor/xregexp/xregexp.js', - 'public/vendor/xregexp/unicode/unicode-base.js', - 'public/src/utils.js', - 'public/src/installer/install.js' - ]; +var web = {}; +var scripts = [ + 'public/vendor/xregexp/xregexp.js', + 'public/vendor/xregexp/unicode/unicode-base.js', + 'public/src/utils.js', + 'public/src/installer/install.js' +]; web.install = function(port) { port = port || 4567; @@ -62,22 +62,23 @@ function setupRoutes() { } function welcome(req, res) { - var dbs = ['redis', 'mongo'], - databases = []; - - dbs.forEach(function(el) { - databases.push({ + var dbs = ['redis', 'mongo']; + var databases = dbs.map(function(el) { + return { name: el, questions: require('../src/database/' + el).questions - }); + }; }); + var defaults = require('./data/defaults'); + res.render('install/index', { databases: databases, skipDatabaseSetup: !!nconf.get('database'), error: res.locals.error ? true : false, success: res.locals.success ? true : false, - values: req.body + values: req.body, + minimumPasswordLength: defaults.minimumPasswordLength }); } @@ -104,7 +105,6 @@ function install(req, res) { } function launch(req, res) { - var pidFilePath = __dirname + '../pidfile'; res.json({}); server.close(); @@ -146,10 +146,10 @@ function compileJS(callback) { return callback(false); } - var scriptPath = path.join(__dirname, '..'), - result = uglify.minify(scripts.map(function(script) { - return path.join(scriptPath, script); - })); + var scriptPath = path.join(__dirname, '..'); + var result = uglify.minify(scripts.map(function(script) { + return path.join(scriptPath, script); + })); fs.writeFile(path.join(__dirname, '../public/nodebb.min.js'), result.code, callback); diff --git a/public/src/installer/install.js b/public/src/installer/install.js index f7224fb71a..d2e5b64fc8 100644 --- a/public/src/installer/install.js +++ b/public/src/installer/install.js @@ -44,7 +44,7 @@ $('document').ready(function() { if ($('form .admin .error').length) { ev.preventDefault(); $('html, body').animate({'scrollTop': '0px'}, 400); - + return false; } else { $('#submit .fa-spin').removeClass('hide'); @@ -69,6 +69,9 @@ $('document').ready(function() { if (!utils.isPasswordValid(field)) { parent.addClass('error'); help.html('Invalid Password.'); + } else if (field.length < $('[name="admin:password"]').attr('data-minimum-length')) { + parent.addClass('error'); + help.html('Password is too short.'); } else { parent.removeClass('error'); } diff --git a/src/views/install/index.tpl b/src/views/install/index.tpl index 75d6c1e16a..9621632a73 100644 --- a/src/views/install/index.tpl +++ b/src/views/install/index.tpl @@ -72,9 +72,9 @@
    - +
    -
    +
    @@ -119,7 +119,7 @@

    Congratulations! Your NodeBB has been set-up.

    - +

    @@ -136,7 +136,7 @@
    - +
    From bc255110cc6316a65ef610edc4fb02cd04a9717c Mon Sep 17 00:00:00 2001 From: barisusakli Date: Fri, 12 Aug 2016 01:55:38 +0300 Subject: [PATCH 32/63] closes #2832 --- public/src/admin/manage/users.js | 22 +++++++++++++++++++++- src/socket.io/admin/user.js | 18 +++++++++++++++--- src/views/admin/manage/users.tpl | 1 + 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/public/src/admin/manage/users.js b/public/src/admin/manage/users.js index cc39889807..7138bb01b9 100644 --- a/public/src/admin/manage/users.js +++ b/public/src/admin/manage/users.js @@ -195,7 +195,7 @@ define('admin/manage/users', ['admin/modules/selectable'], function(selectable) return; } - bootbox.confirm('Warning!
    Do you really want to delete user(s)?
    This action is not reversable, all user data and content will be erased!', function(confirm) { + bootbox.confirm('Warning!
    Do you really want to delete user(s)?
    This action is not reversable, only the user account will be deleted, their posts and topics will not be deleled!', function(confirm) { if (confirm) { socket.emit('admin.user.deleteUsers', uids, function(err) { if (err) { @@ -210,6 +210,26 @@ define('admin/manage/users', ['admin/modules/selectable'], function(selectable) }); }); + $('.delete-user-and-content').on('click', function() { + var uids = getSelectedUids(); + if (!uids.length) { + return; + } + bootbox.confirm('Warning!
    Do you really want to delete user(s) and their content?
    This action is not reversable, all user data and content will be erased!', function(confirm) { + if (confirm) { + socket.emit('admin.user.deleteUsersAndContent', uids, function(err) { + if (err) { + return app.alertError(err.message); + } + + app.alertSuccess('User(s) Deleted!'); + removeSelected(); + unselectAll(); + }); + } + }); + }); + function handleUserCreate() { var errorEl = $('#create-modal-error'); $('#createUser').on('click', function() { diff --git a/src/socket.io/admin/user.js b/src/socket.io/admin/user.js index ed7b4b378d..3fd69a8d10 100644 --- a/src/socket.io/admin/user.js +++ b/src/socket.io/admin/user.js @@ -142,7 +142,19 @@ User.sendPasswordResetEmail = function(socket, uids, callback) { }; User.deleteUsers = function(socket, uids, callback) { - if(!Array.isArray(uids)) { + deleteUsers(socket, uids, function(uid, next) { + user.deleteAccount(uid, next); + }, callback); +}; + +User.deleteUsersAndContent = function(socket, uids, callback) { + deleteUsers(socket, uids, function(uid, next) { + user.delete(socket.uid, uid, next); + }, callback); +}; + +function deleteUsers(socket, uids, method, callback) { + if (!Array.isArray(uids)) { return callback(new Error('[[error:invalid-data]]')); } @@ -156,7 +168,7 @@ User.deleteUsers = function(socket, uids, callback) { return next(new Error('[[error:cant-delete-other-admins]]')); } - user.delete(socket.uid, uid, next); + method(uid, next); }, function (next) { events.log({ @@ -169,7 +181,7 @@ User.deleteUsers = function(socket, uids, callback) { } ], next); }, callback); -}; +} User.search = function(socket, data, callback) { user.search({query: data.query, searchBy: data.searchBy, uid: socket.uid}, function(err, searchData) { diff --git a/src/views/admin/manage/users.tpl b/src/views/admin/manage/users.tpl index 6683f6e887..d6dd8c5a25 100644 --- a/src/views/admin/manage/users.tpl +++ b/src/views/admin/manage/users.tpl @@ -30,6 +30,7 @@
  • Reset Flags
  • Delete User(s)
  • +
  • Delete User(s) and Content
  • From b5bf2737e4b84f4548a4f6384fb835b5d376d87c Mon Sep 17 00:00:00 2001 From: barisusakli Date: Fri, 12 Aug 2016 02:09:11 +0300 Subject: [PATCH 33/63] bind to regular function --- src/socket.io/user/ban.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/socket.io/user/ban.js b/src/socket.io/user/ban.js index d52251d76d..070fdf5566 100644 --- a/src/socket.io/user/ban.js +++ b/src/socket.io/user/ban.js @@ -16,7 +16,9 @@ module.exports = function(SocketUser) { } } - toggleBan(socket.uid, data.uids, banUser.bind(null, data.until || 0), function(err) { + toggleBan(socket.uid, data.uids, function(uid, next) { + banUser(data.until || 0, uid, next); + }, function(err) { if (err) { return callback(err); } From 7d4ef3907ff8503fa4931d2e164c8f44353c87b5 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Fri, 12 Aug 2016 02:09:52 +0300 Subject: [PATCH 34/63] fix semicolons --- src/socket.io/user/ban.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/socket.io/user/ban.js b/src/socket.io/user/ban.js index 070fdf5566..a2c4ea50d3 100644 --- a/src/socket.io/user/ban.js +++ b/src/socket.io/user/ban.js @@ -13,7 +13,7 @@ module.exports = function(SocketUser) { data = { uids: data, until: 0 - } + }; } toggleBan(socket.uid, data.uids, function(uid, next) { @@ -71,7 +71,6 @@ module.exports = function(SocketUser) { next(); } ], callback); - }; - + } }; From c4eb1c92a8944ca2db82744ae6a1247f1ccfbc14 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Fri, 12 Aug 2016 02:46:19 +0300 Subject: [PATCH 35/63] fix some tests --- tests/database/sorted.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/database/sorted.js b/tests/database/sorted.js index 5c34c380b8..dac17243ea 100644 --- a/tests/database/sorted.js +++ b/tests/database/sorted.js @@ -54,7 +54,7 @@ describe('Sorted Set methods', function() { db.getSortedSetRange('sortedSetTest1', 0, 0, function(err, value) { assert.equal(err, null); assert.equal(arguments.length, 2); - assert.equal(value, 'value1'); + assert.deepStrictEqual(value, ['value1']); done(); }); }); @@ -63,7 +63,7 @@ describe('Sorted Set methods', function() { db.getSortedSetRange('sortedSetTest1', 0, -1, function(err, values) { assert.equal(err, null); assert.equal(arguments.length, 2); - assert.deepEqual(values, ['value1', 'value2', 'value3']); + assert.deepStrictEqual(values, ['value1', 'value2', 'value3']); done(); }); }); @@ -74,7 +74,7 @@ describe('Sorted Set methods', function() { db.getSortedSetRevRange('sortedSetTest1', 0, 0, function(err, value) { assert.equal(err, null); assert.equal(arguments.length, 2); - assert.equal(value, 'value3'); + assert.deepStrictEqual(value, ['value3']); done(); }); }); @@ -83,7 +83,7 @@ describe('Sorted Set methods', function() { db.getSortedSetRevRange('sortedSetTest1', 0, -1, function(err, values) { assert.equal(err, null); assert.equal(arguments.length, 2); - assert.deepEqual(values, ['value3', 'value2', 'value1']); + assert.deepStrictEqual(values, ['value3', 'value2', 'value1']); done(); }); }); @@ -94,7 +94,7 @@ describe('Sorted Set methods', function() { db.getSortedSetRangeWithScores('sortedSetTest1', 0, -1, function(err, values) { assert.equal(err, null); assert.equal(arguments.length, 2); - assert.deepEqual(values, [{value: 'value1', score: 1}, {value: 'value2', score: 2}, {value: 'value3', score: 3}]); + assert.deepStrictEqual(values, [{value: 'value1', score: 1}, {value: 'value2', score: 2}, {value: 'value3', score: 3}]); done(); }); }); @@ -105,7 +105,7 @@ describe('Sorted Set methods', function() { db.getSortedSetRevRangeWithScores('sortedSetTest1', 0, -1, function(err, values) { assert.equal(err, null); assert.equal(arguments.length, 2); - assert.deepEqual(values, [{value: 'value3', score: 3}, {value: 'value2', score: 2}, {value: 'value1', score: 1}]); + assert.deepStrictEqual(values, [{value: 'value3', score: 3}, {value: 'value2', score: 2}, {value: 'value1', score: 1}]); done(); }); }); @@ -116,7 +116,7 @@ describe('Sorted Set methods', function() { db.getSortedSetRangeByScore('sortedSetTest1', 0, -1, '-inf', 2, function(err, values) { assert.equal(err, null); assert.equal(arguments.length, 2); - assert.deepEqual(values, ['value1', 'value2']); + assert.deepStrictEqual(values, ['value1', 'value2']); done(); }); }); @@ -127,7 +127,7 @@ describe('Sorted Set methods', function() { db.getSortedSetRevRangeByScore('sortedSetTest1', 0, -1, '+inf', 2, function(err, values) { assert.equal(err, null); assert.equal(arguments.length, 2); - assert.deepEqual(values, ['value3', 'value2']); + assert.deepStrictEqual(values, ['value3', 'value2']); done(); }); }); @@ -138,7 +138,7 @@ describe('Sorted Set methods', function() { db.getSortedSetRangeByScoreWithScores('sortedSetTest1', 0, -1, '-inf', 2, function(err, values) { assert.equal(err, null); assert.equal(arguments.length, 2); - assert.deepEqual(values, [{value: 'value1', score: 1}, {value: 'value2', score: 2}]); + assert.deepStrictEqual(values, [{value: 'value1', score: 1}, {value: 'value2', score: 2}]); done(); }); }); @@ -149,7 +149,7 @@ describe('Sorted Set methods', function() { db.getSortedSetRevRangeByScoreWithScores('sortedSetTest1', 0, -1, '+inf', 2, function(err, values) { assert.equal(err, null); assert.equal(arguments.length, 2); - assert.deepEqual(values, [{value: 'value3', score: 3}, {value: 'value2', score: 2}]); + assert.deepStrictEqual(values, [{value: 'value3', score: 3}, {value: 'value2', score: 2}]); done(); }); }); From 63f5cd0c79f60bacaf94ec9b6d93825e534f8aa9 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Fri, 12 Aug 2016 02:59:19 +0300 Subject: [PATCH 36/63] removed deepStrictEqual --- tests/database/sorted.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/database/sorted.js b/tests/database/sorted.js index dac17243ea..9705f4fff1 100644 --- a/tests/database/sorted.js +++ b/tests/database/sorted.js @@ -54,7 +54,7 @@ describe('Sorted Set methods', function() { db.getSortedSetRange('sortedSetTest1', 0, 0, function(err, value) { assert.equal(err, null); assert.equal(arguments.length, 2); - assert.deepStrictEqual(value, ['value1']); + assert.deepEqual(value, ['value1']); done(); }); }); @@ -63,7 +63,7 @@ describe('Sorted Set methods', function() { db.getSortedSetRange('sortedSetTest1', 0, -1, function(err, values) { assert.equal(err, null); assert.equal(arguments.length, 2); - assert.deepStrictEqual(values, ['value1', 'value2', 'value3']); + assert.deepEqual(values, ['value1', 'value2', 'value3']); done(); }); }); @@ -74,7 +74,7 @@ describe('Sorted Set methods', function() { db.getSortedSetRevRange('sortedSetTest1', 0, 0, function(err, value) { assert.equal(err, null); assert.equal(arguments.length, 2); - assert.deepStrictEqual(value, ['value3']); + assert.deepEqual(value, ['value3']); done(); }); }); @@ -83,7 +83,7 @@ describe('Sorted Set methods', function() { db.getSortedSetRevRange('sortedSetTest1', 0, -1, function(err, values) { assert.equal(err, null); assert.equal(arguments.length, 2); - assert.deepStrictEqual(values, ['value3', 'value2', 'value1']); + assert.deepEqual(values, ['value3', 'value2', 'value1']); done(); }); }); @@ -94,7 +94,7 @@ describe('Sorted Set methods', function() { db.getSortedSetRangeWithScores('sortedSetTest1', 0, -1, function(err, values) { assert.equal(err, null); assert.equal(arguments.length, 2); - assert.deepStrictEqual(values, [{value: 'value1', score: 1}, {value: 'value2', score: 2}, {value: 'value3', score: 3}]); + assert.deepEqual(values, [{value: 'value1', score: 1}, {value: 'value2', score: 2}, {value: 'value3', score: 3}]); done(); }); }); @@ -105,7 +105,7 @@ describe('Sorted Set methods', function() { db.getSortedSetRevRangeWithScores('sortedSetTest1', 0, -1, function(err, values) { assert.equal(err, null); assert.equal(arguments.length, 2); - assert.deepStrictEqual(values, [{value: 'value3', score: 3}, {value: 'value2', score: 2}, {value: 'value1', score: 1}]); + assert.deepEqual(values, [{value: 'value3', score: 3}, {value: 'value2', score: 2}, {value: 'value1', score: 1}]); done(); }); }); @@ -116,7 +116,7 @@ describe('Sorted Set methods', function() { db.getSortedSetRangeByScore('sortedSetTest1', 0, -1, '-inf', 2, function(err, values) { assert.equal(err, null); assert.equal(arguments.length, 2); - assert.deepStrictEqual(values, ['value1', 'value2']); + assert.deepEqual(values, ['value1', 'value2']); done(); }); }); @@ -127,7 +127,7 @@ describe('Sorted Set methods', function() { db.getSortedSetRevRangeByScore('sortedSetTest1', 0, -1, '+inf', 2, function(err, values) { assert.equal(err, null); assert.equal(arguments.length, 2); - assert.deepStrictEqual(values, ['value3', 'value2']); + assert.deepEqual(values, ['value3', 'value2']); done(); }); }); @@ -138,7 +138,7 @@ describe('Sorted Set methods', function() { db.getSortedSetRangeByScoreWithScores('sortedSetTest1', 0, -1, '-inf', 2, function(err, values) { assert.equal(err, null); assert.equal(arguments.length, 2); - assert.deepStrictEqual(values, [{value: 'value1', score: 1}, {value: 'value2', score: 2}]); + assert.deepEqual(values, [{value: 'value1', score: 1}, {value: 'value2', score: 2}]); done(); }); }); @@ -149,7 +149,7 @@ describe('Sorted Set methods', function() { db.getSortedSetRevRangeByScoreWithScores('sortedSetTest1', 0, -1, '+inf', 2, function(err, values) { assert.equal(err, null); assert.equal(arguments.length, 2); - assert.deepStrictEqual(values, [{value: 'value3', score: 3}, {value: 'value2', score: 2}]); + assert.deepEqual(values, [{value: 'value3', score: 3}, {value: 'value2', score: 2}]); done(); }); }); From 0efe315790deed2632e1a27babbac0189cd8a20f Mon Sep 17 00:00:00 2001 From: barisusakli Date: Fri, 12 Aug 2016 12:57:23 +0300 Subject: [PATCH 37/63] closes #4631 --- public/src/client/topic/events.js | 2 +- public/src/client/topic/posts.js | 2 +- public/src/client/topic/threadTools.js | 26 ++++++++++++++++++++++---- src/privileges/topics.js | 15 +++++++++------ src/topics/create.js | 4 ++++ src/topics/posts.js | 2 +- 6 files changed, 38 insertions(+), 13 deletions(-) diff --git a/public/src/client/topic/events.js b/public/src/client/topic/events.js index 0c6ee5ea06..68a864198e 100644 --- a/public/src/client/topic/events.js +++ b/public/src/client/topic/events.js @@ -188,7 +188,7 @@ define('forum/topic/events', [ var isDeleted = postEl.hasClass('deleted'); postTools.toggle(data.pid, isDeleted); - if (!app.user.isAdmin && !app.user.isGlobalMod && parseInt(data.uid, 10) !== parseInt(app.user.uid, 10)) { + if (!ajaxify.data.privileges.isAdminOrMod && parseInt(data.uid, 10) !== parseInt(app.user.uid, 10)) { postEl.find('[component="post/tools"]').toggleClass('hidden', isDeleted); if (isDeleted) { postEl.find('[component="post/content"]').translateHtml('[[topic:post_is_deleted]]'); diff --git a/public/src/client/topic/posts.js b/public/src/client/topic/posts.js index b31b5fc0ed..656364b3a1 100644 --- a/public/src/client/topic/posts.js +++ b/public/src/client/topic/posts.js @@ -31,7 +31,7 @@ define('forum/topic/posts', [ post.display_delete_tools = (ajaxify.data.privileges['posts:delete'] && post.selfPost) || ajaxify.data.privileges.isAdminOrMod; post.display_moderator_tools = post.display_edit_tools || post.display_delete_tools; post.display_move_tools = ajaxify.data.privileges.isAdminOrMod; - post.display_post_menu = ajaxify.data.privileges.isAdminOrMod || post.selfPost || ((app.user.uid || ajaxify.data.postSharing.length) && !post.deleted); + post.display_post_menu = ajaxify.data.privileges.isAdminOrMod || (post.selfPost && !ajaxify.data.locked) || ((app.user.uid || ajaxify.data.postSharing.length) && !post.deleted); }); updatePostCounts(data.posts); diff --git a/public/src/client/topic/threadTools.js b/public/src/client/topic/threadTools.js index 3110b92a4d..a18c069cd5 100644 --- a/public/src/client/topic/threadTools.js +++ b/public/src/client/topic/threadTools.js @@ -173,15 +173,24 @@ define('forum/topic/threadTools', [ return; } - var isLocked = data.isLocked && !app.user.isAdmin; + var isLocked = data.isLocked && !ajaxify.data.privileges.isAdminOrMod; components.get('topic/lock').toggleClass('hidden', data.isLocked); components.get('topic/unlock').toggleClass('hidden', !data.isLocked); - components.get('topic/reply/container').toggleClass('hidden', isLocked); - components.get('topic/reply/locked').toggleClass('hidden', !isLocked); - threadEl.find('[component="post/reply"], [component="post/quote"], [component="post/edit"], [component="post/delete"]').toggleClass('hidden', isLocked); + var hideReply = (data.isLocked || ajaxify.data.deleted) && !ajaxify.data.privileges.isAdminOrMod; + + components.get('topic/reply/container').toggleClass('hidden', hideReply); + components.get('topic/reply/locked').toggleClass('hidden', ajaxify.data.privileges.isAdminOrMod || !data.isLocked || ajaxify.data.deleted); + + threadEl.find('[component="post"]:not(.deleted) [component="post/reply"], [component="post"]:not(.deleted) [component="post/quote"]').toggleClass('hidden', hideReply); + threadEl.find('[component="post/edit"], [component="post/delete"]').toggleClass('hidden', isLocked); + + threadEl.find('[component="post"][data-uid="'+app.user.uid+'"].deleted [component="post/tools"]').toggleClass('hidden', isLocked); + $('[component="post/header"] i.fa-lock').toggleClass('hidden', !data.isLocked); + $('[component="post/tools"] .dropdown-menu').html(''); + ajaxify.data.locked = data.isLocked; }; ThreadTools.setDeleteState = function(data) { @@ -195,9 +204,17 @@ define('forum/topic/threadTools', [ components.get('topic/purge').toggleClass('hidden', !data.isDelete); components.get('topic/deleted/message').toggleClass('hidden', !data.isDelete); + var hideReply = data.isDelete && !ajaxify.data.privileges.isAdminOrMod; + + components.get('topic/reply/container').toggleClass('hidden', hideReply); + components.get('topic/reply/locked').toggleClass('hidden', ajaxify.data.privileges.isAdminOrMod || !ajaxify.data.locked || data.isDelete); + threadEl.find('[component="post"]:not(.deleted) [component="post/reply"], [component="post"]:not(.deleted) [component="post/quote"]').toggleClass('hidden', hideReply); + threadEl.toggleClass('deleted', data.isDelete); + ajaxify.data.deleted = data.isDelete; }; + ThreadTools.setPinnedState = function(data) { var threadEl = components.get('topic'); if (parseInt(data.tid, 10) !== parseInt(threadEl.attr('data-tid'), 10)) { @@ -207,6 +224,7 @@ define('forum/topic/threadTools', [ components.get('topic/pin').toggleClass('hidden', data.isPinned); components.get('topic/unpin').toggleClass('hidden', !data.isPinned); $('[component="post/header"] i.fa-thumb-tack').toggleClass('hidden', !data.isPinned); + ajaxify.data.pinned = data.isPinned; }; function setFollowState(state) { diff --git a/src/privileges/topics.js b/src/privileges/topics.js index c9f0ec717a..b6fffb8a6a 100644 --- a/src/privileges/topics.js +++ b/src/privileges/topics.js @@ -17,7 +17,7 @@ module.exports = function(privileges) { privileges.topics.get = function(tid, uid, callback) { var topic; async.waterfall([ - async.apply(topics.getTopicFields, tid, ['cid', 'uid', 'locked']), + async.apply(topics.getTopicFields, tid, ['cid', 'uid', 'locked', 'deleted']), function(_topic, next) { topic = _topic; async.parallel({ @@ -42,14 +42,19 @@ module.exports = function(privileges) { var disabled = parseInt(results.disabled, 10) === 1; var locked = parseInt(topic.locked, 10) === 1; + var deleted = parseInt(topic.deleted, 10) === 1; + var isAdminOrMod = results.isAdministrator || results.isModerator; var editable = isAdminOrMod; var deletable = isAdminOrMod || (results.isOwner && results['topics:delete'][0]); plugins.fireHook('filter:privileges.topics.get', { - 'topics:reply': (results['topics:reply'][0] && !locked) || isAdminOrMod, - read: results.read[0] || isAdminOrMod, + 'topics:reply': (results['topics:reply'][0] && !locked && !deleted) || isAdminOrMod, 'topics:read': results['topics:read'][0] || isAdminOrMod, + 'topics:delete': (results.isOwner && results['topics:delete'][0]) || isAdminOrMod, + 'posts:edit': (results['posts:edit'][0] && !locked) || isAdminOrMod, + 'posts:delete': (results['posts:delete'][0] && !locked) || isAdminOrMod, + read: results.read[0] || isAdminOrMod, view_thread_tools: editable || deletable, editable: editable, deletable: deletable, @@ -57,9 +62,7 @@ module.exports = function(privileges) { isAdminOrMod: isAdminOrMod, disabled: disabled, tid: tid, - uid: uid, - 'posts:edit': (results['posts:edit'][0] && !locked) || isAdminOrMod, - 'posts:delete': (results['posts:delete'][0] && !locked) || isAdminOrMod + uid: uid }, callback); }); }; diff --git a/src/topics/create.js b/src/topics/create.js index c79e0758f4..cd1bf23a62 100644 --- a/src/topics/create.js +++ b/src/topics/create.js @@ -205,6 +205,10 @@ module.exports = function(Topics) { return next(new Error('[[error:topic-locked]]')); } + if (parseInt(results.topicData.deleted, 10) === 1 && !results.isAdminOrMod) { + return next(new Error('[[error:topic-deleted]]')); + } + if (!results.canReply) { return next(new Error('[[error:no-privileges]]')); } diff --git a/src/topics/posts.js b/src/topics/posts.js index 45e46cd3c8..80bde62334 100644 --- a/src/topics/posts.js +++ b/src/topics/posts.js @@ -145,7 +145,7 @@ module.exports = function(Topics) { post.display_delete_tools = topicPrivileges.isAdminOrMod || (post.selfPost && topicPrivileges['posts:delete']); post.display_moderator_tools = post.display_edit_tools || post.display_delete_tools; post.display_move_tools = topicPrivileges.isAdminOrMod && post.index !== 0; - post.display_post_menu = topicPrivileges.isAdminOrMod || post.selfPost || ((loggedIn || topicData.postSharing.length) && !post.deleted); + post.display_post_menu = topicPrivileges.isAdminOrMod || (post.selfPost && !topicData.locked) || ((loggedIn || topicData.postSharing.length) && !post.deleted); post.ip = topicPrivileges.isAdminOrMod ? post.ip : undefined; if (post.deleted && !(topicPrivileges.isAdminOrMod || post.selfPost)) { From 4ca53703e33018705cc759280a80ee2913579e1e Mon Sep 17 00:00:00 2001 From: barisusakli Date: Fri, 12 Aug 2016 13:41:49 +0300 Subject: [PATCH 38/63] added dupe group create test --- tests/groups.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/groups.js b/tests/groups.js index 81fb253433..a86495071f 100644 --- a/tests/groups.js +++ b/tests/groups.js @@ -162,6 +162,14 @@ describe('Groups', function() { Groups.get('foo', {}, done); }); }); + + it('should fail to create group with duplicate group name', function(done) { + Groups.create({name: 'foo'}, function(err) { + assert(err); + assert.equal(err.message, '[[error:group-already-exists]]'); + done(); + }); + }); }); describe('.hide()', function() { From a13bc64f402fe44c758d082b6298fec8e5ee5839 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Fri, 12 Aug 2016 13:49:41 +0300 Subject: [PATCH 39/63] wait for db flush to complete to carry on with other test suites fixes the problem where tests would sometimes fail due to timing issues --- tests/categories.js | 4 ++-- tests/database/hash.js | 4 ++-- tests/database/keys.js | 4 ++-- tests/database/list.js | 4 ++-- tests/database/sets.js | 4 ++-- tests/database/sorted.js | 4 ++-- tests/groups.js | 4 ++-- tests/messaging.js | 4 ++-- tests/topics.js | 4 ++-- tests/user.js | 4 ++-- 10 files changed, 20 insertions(+), 20 deletions(-) diff --git a/tests/categories.js b/tests/categories.js index 7115b88597..4ec06ab3b4 100644 --- a/tests/categories.js +++ b/tests/categories.js @@ -89,7 +89,7 @@ describe('Categories', function() { }); }); - after(function() { - db.flushdb(); + after(function(done) { + db.flushdb(done); }); }); diff --git a/tests/database/hash.js b/tests/database/hash.js index 469172ce70..a178280e3c 100644 --- a/tests/database/hash.js +++ b/tests/database/hash.js @@ -369,7 +369,7 @@ describe('Hash methods', function() { - after(function() { - db.flushdb(); + after(function(done) { + db.flushdb(done); }); }); diff --git a/tests/database/keys.js b/tests/database/keys.js index 36e5fe5989..832c91bcba 100644 --- a/tests/database/keys.js +++ b/tests/database/keys.js @@ -142,7 +142,7 @@ describe('Key methods', function() { }); - after(function() { - db.flushdb(); + after(function(done) { + db.flushdb(done); }); }); diff --git a/tests/database/list.js b/tests/database/list.js index 59fa82aa58..137c465c2e 100644 --- a/tests/database/list.js +++ b/tests/database/list.js @@ -158,7 +158,7 @@ describe('List methods', function() { }); - after(function() { - db.flushdb(); + after(function(done) { + db.flushdb(done); }); }); diff --git a/tests/database/sets.js b/tests/database/sets.js index a7a23f4dd8..2b852a5341 100644 --- a/tests/database/sets.js +++ b/tests/database/sets.js @@ -229,7 +229,7 @@ describe('Set methods', function() { }); - after(function() { - db.flushdb(); + after(function(done) { + db.flushdb(done); }); }); diff --git a/tests/database/sorted.js b/tests/database/sorted.js index 9705f4fff1..64e8891a30 100644 --- a/tests/database/sorted.js +++ b/tests/database/sorted.js @@ -533,7 +533,7 @@ describe('Sorted Set methods', function() { }); - after(function() { - db.flushdb(); + after(function(done) { + db.flushdb(done); }); }); diff --git a/tests/groups.js b/tests/groups.js index a86495071f..6c30bddd77 100644 --- a/tests/groups.js +++ b/tests/groups.js @@ -342,7 +342,7 @@ describe('Groups', function() { }); }); - after(function() { - db.flushdb(); + after(function(done) { + db.flushdb(done); }); }); diff --git a/tests/messaging.js b/tests/messaging.js index 4758fde40b..3092e42b35 100644 --- a/tests/messaging.js +++ b/tests/messaging.js @@ -66,7 +66,7 @@ describe('Messaging Library', function() { }); }); - after(function() { - db.flushdb(); + after(function(done) { + db.flushdb(done); }); }); diff --git a/tests/topics.js b/tests/topics.js index 0c04d875bf..dcf7f1067e 100644 --- a/tests/topics.js +++ b/tests/topics.js @@ -387,7 +387,7 @@ describe('Topic\'s', function() { }); }); - after(function() { - db.flushdb(); + after(function(done) { + db.flushdb(done); }); }); diff --git a/tests/user.js b/tests/user.js index 570b002808..30a835fe83 100644 --- a/tests/user.js +++ b/tests/user.js @@ -282,7 +282,7 @@ describe('User', function() { }); }); - after(function() { - db.flushdb(); + after(function(done) { + db.flushdb(done); }); }); \ No newline at end of file From 650f4d6ed535daebd6e31a9fe5c4209351df9bbf Mon Sep 17 00:00:00 2001 From: barisusakli Date: Fri, 12 Aug 2016 14:11:40 +0300 Subject: [PATCH 40/63] moved sitemap to its own file --- src/controllers/index.js | 63 ++--------------------------------- src/controllers/sitemap.js | 68 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 61 deletions(-) create mode 100644 src/controllers/sitemap.js diff --git a/src/controllers/index.js b/src/controllers/index.js index bd6daa6581..4ad3d5ab0a 100644 --- a/src/controllers/index.js +++ b/src/controllers/index.js @@ -8,7 +8,6 @@ var winston = require('winston'); var meta = require('../meta'); var user = require('../user'); var plugins = require('../plugins'); -var sitemap = require('../sitemap'); var helpers = require('./helpers'); var Controllers = { @@ -27,7 +26,8 @@ var Controllers = { authentication: require('./authentication'), api: require('./api'), admin: require('./admin'), - globalMods: require('./globalmods') + globalMods: require('./globalmods'), + sitemap: require('./sitemap') }; @@ -251,65 +251,6 @@ Controllers.confirmEmail = function(req, res) { }); }; -Controllers.sitemap = {}; -Controllers.sitemap.render = function(req, res, next) { - sitemap.render(function(err, tplData) { - if (err) { - return next(err); - } - - Controllers.render('sitemap', tplData, function(err, xml) { - res.header('Content-Type', 'application/xml'); - res.send(xml); - }); - }); -}; - -Controllers.sitemap.getPages = function(req, res, next) { - if (parseInt(meta.config['feeds:disableSitemap'], 10) === 1) { - return next(); - } - - sitemap.getPages(function(err, xml) { - if (err) { - return next(err); - } - res.header('Content-Type', 'application/xml'); - res.send(xml); - }); -}; - -Controllers.sitemap.getCategories = function(req, res, next) { - if (parseInt(meta.config['feeds:disableSitemap'], 10) === 1) { - return next(); - } - - sitemap.getCategories(function(err, xml) { - if (err) { - return next(err); - } - res.header('Content-Type', 'application/xml'); - res.send(xml); - }); -}; - -Controllers.sitemap.getTopicPage = function(req, res, next) { - if (parseInt(meta.config['feeds:disableSitemap'], 10) === 1) { - return next(); - } - - sitemap.getTopicPage(parseInt(req.params[0], 10), function(err, xml) { - if (err) { - return next(err); - } else if (!xml) { - return next(); - } - - res.header('Content-Type', 'application/xml'); - res.send(xml); - }); -}; - Controllers.robots = function (req, res) { res.set('Content-Type', 'text/plain'); diff --git a/src/controllers/sitemap.js b/src/controllers/sitemap.js new file mode 100644 index 0000000000..eee344fc92 --- /dev/null +++ b/src/controllers/sitemap.js @@ -0,0 +1,68 @@ +'use strict'; + +var sitemap = require('../sitemap'); +var meta = require('../meta'); + +var sitemapController = {}; +sitemapController.render = function(req, res, next) { + sitemap.render(function(err, tplData) { + if (err) { + return next(err); + } + var Controllers = require('./index'); + Controllers.render('sitemap', tplData, function(err, xml) { + if (err) { + return next(err); + } + res.header('Content-Type', 'application/xml'); + res.send(xml); + }); + }); +}; + +sitemapController.getPages = function(req, res, next) { + if (parseInt(meta.config['feeds:disableSitemap'], 10) === 1) { + return next(); + } + + sitemap.getPages(function(err, xml) { + if (err) { + return next(err); + } + res.header('Content-Type', 'application/xml'); + res.send(xml); + }); +}; + +sitemapController.getCategories = function(req, res, next) { + if (parseInt(meta.config['feeds:disableSitemap'], 10) === 1) { + return next(); + } + + sitemap.getCategories(function(err, xml) { + if (err) { + return next(err); + } + res.header('Content-Type', 'application/xml'); + res.send(xml); + }); +}; + +sitemapController.getTopicPage = function(req, res, next) { + if (parseInt(meta.config['feeds:disableSitemap'], 10) === 1) { + return next(); + } + + sitemap.getTopicPage(parseInt(req.params[0], 10), function(err, xml) { + if (err) { + return next(err); + } else if (!xml) { + return next(); + } + + res.header('Content-Type', 'application/xml'); + res.send(xml); + }); +}; + +module.exports = sitemapController; \ No newline at end of file From b9ad7f2dbb896d9d040ad48db34abbe4ec715821 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Fri, 12 Aug 2016 15:06:03 +0300 Subject: [PATCH 41/63] remove unused group code from settings --- src/controllers/accounts/settings.js | 10 ---------- src/user/settings.js | 1 - 2 files changed, 11 deletions(-) diff --git a/src/controllers/accounts/settings.js b/src/controllers/accounts/settings.js index 483a7e5eb1..9efa8ebe6b 100644 --- a/src/controllers/accounts/settings.js +++ b/src/controllers/accounts/settings.js @@ -32,9 +32,6 @@ settingsController.get = function(req, res, callback) { settings: function(next) { user.getSettings(userData.uid, next); }, - userGroups: function(next) { - groups.getUserGroupsFromSet('groups:createtime', [userData.uid], next); - }, languages: function(next) { languages.list(next); }, @@ -49,9 +46,6 @@ settingsController.get = function(req, res, callback) { }, function(results, next) { userData.settings = results.settings; - userData.userGroups = results.userGroups[0].filter(function(group) { - return group && group.userTitleEnabled && !groups.isPrivilegeGroup(group.name) && group.name !== 'registered-users'; - }); userData.languages = results.languages; userData.homePageRoutes = results.homePageRoutes; userData.ips = results.ips; @@ -118,10 +112,6 @@ settingsController.get = function(req, res, callback) { skin.selected = skin.value === userData.settings.bootswatchSkin; }); - userData.userGroups.forEach(function(group) { - group.selected = group.name === userData.settings.groupTitle; - }); - userData.languages.forEach(function(language) { language.selected = language.code === userData.settings.userLang; }); diff --git a/src/user/settings.js b/src/user/settings.js index 7b78ea3c72..55bf2b14ff 100644 --- a/src/user/settings.js +++ b/src/user/settings.js @@ -122,7 +122,6 @@ module.exports = function(User) { restrictChat: data.restrictChat, topicSearchEnabled: data.topicSearchEnabled, delayImageLoading: data.delayImageLoading, - groupTitle: data.groupTitle, homePageRoute : ((data.homePageRoute === 'custom' ? data.homePageCustom : data.homePageRoute) || '').replace(/^\//, ''), scrollToMyPost: data.scrollToMyPost }; From 32320018ab875ca79442c25193a6cf36fd6aeb3f Mon Sep 17 00:00:00 2001 From: barisusakli Date: Fri, 12 Aug 2016 15:29:41 +0300 Subject: [PATCH 42/63] closes #4911 --- public/src/app.js | 20 +++++++++++--------- public/src/client/topic/fork.js | 18 +++++++++--------- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/public/src/app.js b/public/src/app.js index 390bde2f04..a913517363 100644 --- a/public/src/app.js +++ b/public/src/app.js @@ -511,20 +511,22 @@ app.cacheBuster = null; app.parseAndTranslate = function(template, blockName, data, callback) { require(['translator'], function(translator) { + function translate(html, callback) { + translator.translate(html, function(translatedHTML) { + translatedHTML = translator.unescape(translatedHTML); + callback($(translatedHTML)); + }); + } + if (typeof blockName === 'string') { templates.parse(template, blockName, data, function(html) { - translator.translate(html, function(translatedHTML) { - translatedHTML = translator.unescape(translatedHTML); - callback($(translatedHTML)); - }); + translate(html, callback); }); } else { - callback = data, data = blockName; + callback = data; + data = blockName; templates.parse(template, data, function(html) { - translator.translate(html, function(translatedHTML) { - translatedHTML = translator.unescape(translatedHTML); - callback($(translatedHTML)); - }); + translate(html, callback); }); } }); diff --git a/public/src/client/topic/fork.js b/public/src/client/topic/fork.js index feb02a9f78..2083a4867e 100644 --- a/public/src/client/topic/fork.js +++ b/public/src/client/topic/fork.js @@ -1,6 +1,6 @@ 'use strict'; -/* globals define, app, ajaxify, socket, templates, translator */ +/* globals define, app, ajaxify, socket */ define('forum/topic/fork', ['components', 'postSelect'], function(components, postSelect) { @@ -10,11 +10,17 @@ define('forum/topic/fork', ['components', 'postSelect'], function(components, po Fork.init = function() { $('.topic').on('click', '[component="topic/fork"]', onForkThreadClicked); + $(window).on('action:ajaxify.start', onAjaxifyStart); }; + function onAjaxifyStart() { + closeForkModal(); + $(window).off('action:ajaxify.start', onAjaxifyStart); + } + function onForkThreadClicked() { - parseModal(function(html) { - forkModal = $(html); + app.parseAndTranslate('partials/fork_thread_modal', {}, function(html) { + forkModal = html; forkCommit = forkModal.find('#fork_thread_commit'); @@ -33,12 +39,6 @@ define('forum/topic/fork', ['components', 'postSelect'], function(components, po }); } - function parseModal(callback) { - templates.parse('partials/fork_thread_modal', {}, function(html) { - translator.translate(html, callback); - }); - } - function createTopicFromPosts() { forkCommit.attr('disabled', true); socket.emit('topics.createTopicFromPosts', { From ad4910d44d87c678b66a82ab8fdf6af18a0de3b3 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Fri, 12 Aug 2016 15:47:11 +0300 Subject: [PATCH 43/63] up async to 2.0.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c9ad9c178f..2ee7dd6323 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "test": "./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha -- ./tests -t 10000" }, "dependencies": { - "async": "~1.5.0", + "async": "~2.0.1", "autoprefixer": "^6.2.3", "bcryptjs": "~2.3.0", "body-parser": "^1.9.0", From ecb4e3ad7c2c62442d2028c7b2e74bbdf831ee84 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Fri, 12 Aug 2016 16:01:01 +0300 Subject: [PATCH 44/63] up deps --- package.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 2ee7dd6323..8d7b5cad95 100644 --- a/package.json +++ b/package.json @@ -23,9 +23,9 @@ "compression": "^1.1.0", "connect-ensure-login": "^0.1.1", "connect-flash": "^0.1.1", - "connect-mongo": "~1.1.0", + "connect-mongo": "~1.3.2", "connect-multiparty": "^2.0.0", - "connect-redis": "~3.0.2", + "connect-redis": "~3.1.0", "cookie-parser": "^1.3.3", "cron": "^1.0.5", "csurf": "^1.6.1", @@ -43,7 +43,7 @@ "mime": "^1.3.4", "minimist": "^1.1.1", "mkdirp": "~0.5.0", - "mongodb": "~2.1.3", + "mongodb": "~2.2.5", "morgan": "^1.3.2", "mousetrap": "^1.5.3", "nconf": "~0.8.2", @@ -67,7 +67,7 @@ "passport-local": "1.0.0", "postcss": "^5.0.13", "prompt": "^1.0.0", - "redis": "~2.4.2", + "redis": "~2.6.2", "request": "^2.44.0", "rimraf": "~2.5.0", "rss": "^1.0.0", @@ -80,7 +80,7 @@ "socketio-wildcard": "~0.3.0", "string": "^3.0.0", "templates.js": "0.3.4", - "toobusy-js": "^0.4.2", + "toobusy-js": "^0.5.1", "uglify-js": "^2.6.0", "underscore": "^1.8.3", "underscore.deep": "^0.5.1", From a5c409c6f7e30f81bc0c4531aea62170e69d911a Mon Sep 17 00:00:00 2001 From: NodeBB Misty Date: Fri, 12 Aug 2016 09:02:39 -0400 Subject: [PATCH 45/63] Latest translations and fallbacks --- public/language/bg/modules.json | 2 +- public/language/fr/modules.json | 2 +- public/language/pt_BR/error.json | 2 +- public/language/pt_BR/modules.json | 2 +- public/language/pt_BR/topic.json | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/public/language/bg/modules.json b/public/language/bg/modules.json index c9cee68f96..e17f98847b 100644 --- a/public/language/bg/modules.json +++ b/public/language/bg/modules.json @@ -37,7 +37,7 @@ "composer.formatting.picture": "Снимка", "composer.upload-picture": "Качване на изображение", "composer.upload-file": "Качване на файл", - "composer.zen_mode": "Zen Mode", + "composer.zen_mode": "Режим Дзен", "bootbox.ok": "Добре", "bootbox.cancel": "Отказ", "bootbox.confirm": "Потвърждаване", diff --git a/public/language/fr/modules.json b/public/language/fr/modules.json index 09746bc86b..9a9eaa0675 100644 --- a/public/language/fr/modules.json +++ b/public/language/fr/modules.json @@ -37,7 +37,7 @@ "composer.formatting.picture": "Image", "composer.upload-picture": "Envoyer une image", "composer.upload-file": "Envoyer un fichier", - "composer.zen_mode": "Zen Mode", + "composer.zen_mode": "Mode Zen", "bootbox.ok": "OK", "bootbox.cancel": "Annuler", "bootbox.confirm": "Confirmer", diff --git a/public/language/pt_BR/error.json b/public/language/pt_BR/error.json index 849a4878a1..64286e8352 100644 --- a/public/language/pt_BR/error.json +++ b/public/language/pt_BR/error.json @@ -20,7 +20,7 @@ "email-taken": "Email já cadastrado", "email-not-confirmed": "O seu email ainda não foi confirmado, por favor clique aqui para confirmar seu email.", "email-not-confirmed-chat": "Você não está habilitado a conversar até que seu email seja confirmado, por favor clique aqui para confirmar seu email.", - "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", + "email-not-confirmed-email-sent": "O seu email ainda não foi confirmado, por favor confira a sua caixa de entrada pelo email de confirmação.", "no-email-to-confirm": "Este fórum exige confirmação de email, por gentileza clique aqui para digitar um email", "email-confirm-failed": "Nós não pudemos confirmar seu email, por gentileza tente novamente mais tarde.", "confirm-email-already-sent": "O email de confirmação já foi enviado, por favor aguarde %1 minuto(s) para enviar outro.", diff --git a/public/language/pt_BR/modules.json b/public/language/pt_BR/modules.json index d9c8e1653d..d02547efe4 100644 --- a/public/language/pt_BR/modules.json +++ b/public/language/pt_BR/modules.json @@ -37,7 +37,7 @@ "composer.formatting.picture": "Imagem", "composer.upload-picture": "Fazer upload de Imagem", "composer.upload-file": "Fazer upload de Arquivo", - "composer.zen_mode": "Zen Mode", + "composer.zen_mode": "Modo Zen", "bootbox.ok": "OK", "bootbox.cancel": "Cancelar", "bootbox.confirm": "Confirmar", diff --git a/public/language/pt_BR/topic.json b/public/language/pt_BR/topic.json index dec0d42e8e..194f00c316 100644 --- a/public/language/pt_BR/topic.json +++ b/public/language/pt_BR/topic.json @@ -86,7 +86,7 @@ "topic_will_be_moved_to": "Este tópico será movido para a categoria", "fork_topic_instruction": "Clique nos posts que você quer ramificar", "fork_no_pids": "Nenhum post selecionado!", - "fork_pid_count": "%1 post(s) selected", + "fork_pid_count": "%1 post(s) selecionado(s)", "fork_success": "Tópico ramificado com sucesso! Clique aqui para ir ao tópico ramificado.", "delete_posts_instruction": "Clique nos posts que você deseja deletar/limpar", "composer.title_placeholder": "Digite aqui o título para o seu tópico...", From 80c096dedb366570d2eae0d5f666f35d4fcc8c10 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Fri, 12 Aug 2016 12:52:44 -0400 Subject: [PATCH 46/63] Revert "up async to 2.0.1" This reverts commit ad4910d44d87c678b66a82ab8fdf6af18a0de3b3. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8d7b5cad95..ef16dbbad1 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "test": "./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha -- ./tests -t 10000" }, "dependencies": { - "async": "~2.0.1", + "async": "~1.5.0", "autoprefixer": "^6.2.3", "bcryptjs": "~2.3.0", "body-parser": "^1.9.0", From 43184935bd9084dbb67e5787ba0e093f9bad563c Mon Sep 17 00:00:00 2001 From: barisusakli Date: Fri, 12 Aug 2016 20:47:43 +0300 Subject: [PATCH 47/63] revert mongodb packages --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index ef16dbbad1..4d457b471a 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "compression": "^1.1.0", "connect-ensure-login": "^0.1.1", "connect-flash": "^0.1.1", - "connect-mongo": "~1.3.2", + "connect-mongo": "~1.1.0", "connect-multiparty": "^2.0.0", "connect-redis": "~3.1.0", "cookie-parser": "^1.3.3", @@ -43,7 +43,7 @@ "mime": "^1.3.4", "minimist": "^1.1.1", "mkdirp": "~0.5.0", - "mongodb": "~2.2.5", + "mongodb": "~2.1.3", "morgan": "^1.3.2", "mousetrap": "^1.5.3", "nconf": "~0.8.2", From 28331389a6fc26e95d04841591f5db1ad74d973d Mon Sep 17 00:00:00 2001 From: barisusakli Date: Sat, 13 Aug 2016 01:20:19 +0300 Subject: [PATCH 48/63] added getTopicWithPosts test --- tests/topics.js | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/tests/topics.js b/tests/topics.js index dcf7f1067e..7103b32689 100644 --- a/tests/topics.js +++ b/tests/topics.js @@ -132,7 +132,7 @@ describe('Topic\'s', function() { var newTopic; var newPost; - beforeEach(function(done) { + before(function(done) { topics.post({uid: topic.userId, title: topic.title, content: topic.content, cid: topic.categoryId}, function(err, result) { newTopic = result.topicData; newPost = result.postData; @@ -145,6 +145,28 @@ describe('Topic\'s', function() { topics.getTopicData(newTopic.tid, done); }); }); + + describe('.getTopicWithPosts', function() { + it('should get a topic with posts and other data', function(done) { + topics.getTopicData(newTopic.tid, function(err, topicData) { + if (err) { + return done(err); + } + topics.getTopicWithPosts(topicData, 'tid:' + newTopic.tid + ':posts', topic.userId, 0, -1, false, function(err, data) { + if (err) { + return done(err); + } + assert(data); + assert.equal(data.category.cid, topic.categoryId); + assert.equal(data.unreplied, true); + assert.equal(data.deleted, false); + assert.equal(data.locked, false); + assert.equal(data.pinned, false); + done(); + }); + }); + }); + }); }); describe('Title escaping', function() { From 85dfe7704fbb1496b3cf067d88ec7a8da80e81aa Mon Sep 17 00:00:00 2001 From: barisusakli Date: Sat, 13 Aug 2016 01:20:27 +0300 Subject: [PATCH 49/63] moved related up --- src/topics.js | 8 +++----- src/topics/tags.js | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/topics.js b/src/topics.js index b92d0b51bf..0079c501ce 100644 --- a/src/topics.js +++ b/src/topics.js @@ -192,7 +192,8 @@ var social = require('./social'); isFollowing: async.apply(Topics.isFollowing, [topicData.tid], uid), isIgnoring: async.apply(Topics.isIgnoring, [topicData.tid], uid), bookmark: async.apply(Topics.getUserBookmark, topicData.tid, uid), - postSharing: async.apply(social.getActivePostSharing) + postSharing: async.apply(social.getActivePostSharing), + related: async.apply(Topics.getRelatedTopics, topicData, uid) }, next); }, function (results, next) { @@ -205,6 +206,7 @@ var social = require('./social'); topicData.isIgnoring = results.isIgnoring[0]; topicData.bookmark = results.bookmark; topicData.postSharing = results.postSharing; + topicData.related = results.related || []; topicData.unreplied = parseInt(topicData.postcount, 10) === 1; topicData.deleted = parseInt(topicData.deleted, 10) === 1; @@ -213,10 +215,6 @@ var social = require('./social'); topicData.icons = []; - Topics.getRelatedTopics(topicData, uid, next); - }, - function (related, next) { - topicData.related = related || []; plugins.fireHook('filter:topic.get', {topic: topicData, uid: uid}, next); }, function (data, next) { diff --git a/src/topics/tags.js b/src/topics/tags.js index 83702331b7..ec16c09ff6 100644 --- a/src/topics/tags.js +++ b/src/topics/tags.js @@ -316,7 +316,7 @@ module.exports = function(Topics) { return plugins.fireHook('filter:topic.getRelatedTopics', {topic: topicData, uid: uid}, callback); } - var maximumTopics = parseInt(meta.config.maximumRelatedTopics, 10); + var maximumTopics = parseInt(meta.config.maximumRelatedTopics, 10) || 0; if (maximumTopics === 0 || !topicData.tags.length) { return callback(null, []); } From de007772a489fd47fffa7f29e3263ba4855f3c9b Mon Sep 17 00:00:00 2001 From: Accalia de Elementia Date: Sat, 13 Aug 2016 12:50:06 +0000 Subject: [PATCH 50/63] feat: Allow listing all groups via websocket also add missing radix to parsing of `after` in groups.loadMore websocket method. --- src/socket.io/groups.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/socket.io/groups.js b/src/socket.io/groups.js index 7d9ce46a70..5df97f80f5 100644 --- a/src/socket.io/groups.js +++ b/src/socket.io/groups.js @@ -217,12 +217,12 @@ SocketGroups.search = function(socket, data, callback) { }; SocketGroups.loadMore = function(socket, data, callback) { - if (!data.sort || !data.after) { + if (!data.sort || !utils.isNumber(data.after) || parseInt(data.after, 10) < 0) { return callback(); } var groupsPerPage = 9; - var start = parseInt(data.after); + var start = parseInt(data.after, 10); var stop = start + groupsPerPage - 1; groupsController.getGroupsFromSet(socket.uid, data.sort, start, stop, callback); }; From fd71b1afb6f323ac920da0a62fca4ba69069f654 Mon Sep 17 00:00:00 2001 From: NodeBB Misty Date: Sat, 13 Aug 2016 09:02:25 -0400 Subject: [PATCH 51/63] Latest translations and fallbacks --- public/language/de/category.json | 2 +- public/language/de/register.json | 8 ++++---- public/language/fa_IR/error.json | 2 +- public/language/fa_IR/modules.json | 2 +- public/language/fa_IR/topic.json | 2 +- public/language/tr/error.json | 2 +- public/language/tr/modules.json | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/public/language/de/category.json b/public/language/de/category.json index 6ce06deed2..9169f01756 100644 --- a/public/language/de/category.json +++ b/public/language/de/category.json @@ -2,7 +2,7 @@ "category": "Kategorie", "subcategories": "Unterkategorien", "new_topic_button": "Neues Thema", - "guest-login-post": "Anmelden, um einen Beitrag zu erstellen", + "guest-login-post": "Melde dich an, um einen Beitrag zu erstellen", "no_topics": "Es gibt noch keine Themen in dieser Kategorie.
    Warum beginnst du nicht eins?", "browsing": "Aktiv", "no_replies": "Niemand hat geantwortet", diff --git a/public/language/de/register.json b/public/language/de/register.json index 41998933f1..9d1b7ca049 100644 --- a/public/language/de/register.json +++ b/public/language/de/register.json @@ -1,6 +1,6 @@ { "register": "Registrieren", - "cancel_registration": "Cancel Registration", + "cancel_registration": "Registrierungsvorgang abbrechen", "help.email": "Deine E-Mail Adresse ist standardmäßig nicht öffentlich sichtbar.", "help.username_restrictions": "Einen einmaligen Benutzernamen. %1-%2 Zeichen. Andere Benutzer können dich mit @Benutzername anschreiben.", "help.minimum_password_length": "Dein Passwort muss mindestens %1 Zeichen lang sein.", @@ -16,8 +16,8 @@ "alternative_registration": "Alternative Registrierung", "terms_of_use": "Nutzungsbedingungen", "agree_to_terms_of_use": "Ich stimme den Nutzungsbedingungen zu", - "terms_of_use_error": "You must agree to the Terms of Use", + "terms_of_use_error": "Du musst den Nutzungsbedingungen zustimmen", "registration-added-to-queue": "Deine Registration wurde abgeschickt. Du wirst eine E-Mail erhalten, sobald sie von einem Administrator akzeptiert wird.", - "interstitial.intro": "We require some additional information before we can create your account.", - "interstitial.errors-found": "We could not complete your registration:" + "interstitial.intro": "Wir benötigen ein wenig mehr Informationen bevor wir deinen Account erstellen können.", + "interstitial.errors-found": "Wir konnten deinen Registrierungsvorgang nicht abschließen:" } \ No newline at end of file diff --git a/public/language/fa_IR/error.json b/public/language/fa_IR/error.json index 0b79d81e23..965f4a00c2 100644 --- a/public/language/fa_IR/error.json +++ b/public/language/fa_IR/error.json @@ -20,7 +20,7 @@ "email-taken": "این ایمیل گرفته شده است.", "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.", + "email-not-confirmed-email-sent": "ایمیل شما هنوز تایید نشده است، لطفا صندوق پیام های خود را برای تایید ایمیل بررسی کنید.", "no-email-to-confirm": "ایمیل شما تایید نشده است ، لطفا برای وارد کردن ایمیل اینجا کلیک کنید", "email-confirm-failed": "سیستم موفق به تایید ایمیل شما نشد، لطفا بعدا دوباره سعی کنید", "confirm-email-already-sent": "ایمیل فعال‌سازی قبلا فرستاده شده، لطفا %1 دقیقه صبر کنید تا ایمیل دیگری بفرستید.", diff --git a/public/language/fa_IR/modules.json b/public/language/fa_IR/modules.json index 20f1a0d8d1..9b39f7cb7f 100644 --- a/public/language/fa_IR/modules.json +++ b/public/language/fa_IR/modules.json @@ -37,7 +37,7 @@ "composer.formatting.picture": "عکس", "composer.upload-picture": "بارگذاری عکس", "composer.upload-file": "بارگذاری فایل", - "composer.zen_mode": "Zen Mode", + "composer.zen_mode": "حالت ذن", "bootbox.ok": "باشه", "bootbox.cancel": "انصراف", "bootbox.confirm": "تایید", diff --git a/public/language/fa_IR/topic.json b/public/language/fa_IR/topic.json index adaf0d29f6..f589a051ef 100644 --- a/public/language/fa_IR/topic.json +++ b/public/language/fa_IR/topic.json @@ -86,7 +86,7 @@ "topic_will_be_moved_to": "این موضوع جابه‌جا خواهد شد به دستهٔ", "fork_topic_instruction": "پست‌هایی را که می‌خواهید به موضوع تازه ببرید، انتخاب کنید", "fork_no_pids": "هیچ پستی انتخاب نشده!", - "fork_pid_count": "%1 post(s) selected", + "fork_pid_count": "%1 پست (ها) انتخاب شده اند", "fork_success": "موضوع با موفقیت منشعب شد! برای رفتن به موضوع انشعابی اینجا را کلیک کنید.", "delete_posts_instruction": "با کلیک بر روی پست شما می خواهید به حذف/پاکسازی", "composer.title_placeholder": "عنوان موضوعتان را اینجا بنویسید...", diff --git a/public/language/tr/error.json b/public/language/tr/error.json index 27385670ed..48811f7373 100644 --- a/public/language/tr/error.json +++ b/public/language/tr/error.json @@ -20,7 +20,7 @@ "email-taken": "E-posta Alınmış", "email-not-confirmed": "E-postanız onaylanmamış, onaylamak için lütfen buraya tıklayın.", "email-not-confirmed-chat": "E-postanız onaylanana kadar sohbet edemezsiniz, onaylamak için lütfen buraya tıklayın.", - "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", + "email-not-confirmed-email-sent": "E-postanız onaylanmamış, onaylamak için lütfen gelen kutunuzu kontrol edin.", "no-email-to-confirm": "Bu forum e-posta doğrulaması gerektirir, lütfen buraya bir e-posta adresi girin", "email-confirm-failed": "E-posta adresinizi doğrulayamıyoruz. Lütfen daha sonra tekrar deneyin.", "confirm-email-already-sent": "E-mail onayı zaten gönderilmiş, yeni bir onay göndermek için lütfen 1 dakika bekleyin.", diff --git a/public/language/tr/modules.json b/public/language/tr/modules.json index 059d8670fb..0edc53c346 100644 --- a/public/language/tr/modules.json +++ b/public/language/tr/modules.json @@ -37,7 +37,7 @@ "composer.formatting.picture": "Görsel", "composer.upload-picture": "Görsel Yükle", "composer.upload-file": "Dosya Yükle", - "composer.zen_mode": "Zen Mode", + "composer.zen_mode": "Zen Modu", "bootbox.ok": "Tamam", "bootbox.cancel": "İptal", "bootbox.confirm": "Onayla", From c8a369f5c3efd102583c9a5f579075cd406dc660 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Sat, 13 Aug 2016 20:02:48 +0300 Subject: [PATCH 52/63] closes #4939 --- src/database/redis/sorted.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/database/redis/sorted.js b/src/database/redis/sorted.js index 0341c043f7..cd1587f494 100644 --- a/src/database/redis/sorted.js +++ b/src/database/redis/sorted.js @@ -110,7 +110,7 @@ module.exports = function(redisClient, module) { } var objects = []; for(var i=0; i Date: Sat, 13 Aug 2016 20:20:13 +0300 Subject: [PATCH 53/63] added database to issue template --- .github/ISSUE_TEMPLATE.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index cc592ac143..28dd965678 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,6 +1,7 @@ Please include the following information when submitting a bug report/issue: * NodeBB version and git hash (to find your git hash, execute `git rev-parse HEAD` from the main NodeBB directory) +* Database (mongo or redis) and it's version. * Exact steps to cause this issue 1. First I did this... 2. Then, I clicked on this item... @@ -9,4 +10,4 @@ Please include the following information when submitting a bug report/issue: * What happened instead * e.g. Instead, I got *zyx* and NodeBB set fire to my house -Thank you! \ No newline at end of file +Thank you! From a7ed5a0129f808a7765c6b7c39eb63f5ad239336 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Sun, 14 Aug 2016 12:59:03 +0300 Subject: [PATCH 54/63] delete content --- public/src/client/account/header.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/src/client/account/header.js b/public/src/client/account/header.js index 616cebbe82..6b39b7f2da 100644 --- a/public/src/client/account/header.js +++ b/public/src/client/account/header.js @@ -152,7 +152,7 @@ define('forum/account/header', [ return; } - socket.emit('admin.user.deleteUsers', [ajaxify.data.theirid], function(err) { + socket.emit('admin.user.deleteUsersAndContent', [ajaxify.data.theirid], function(err) { if (err) { return app.alertError(err.message); } From aad9f83869f07adbf1bd35365b306538ce16ef28 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Sun, 14 Aug 2016 13:13:15 +0300 Subject: [PATCH 55/63] use getSortedRevRangeWithScores, cleanup --- src/user/info.js | 41 ++++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/src/user/info.js b/src/user/info.js index a9ca675eab..da85e25116 100644 --- a/src/user/info.js +++ b/src/user/info.js @@ -1,33 +1,39 @@ 'use strict'; -var async = require('async'), - _ = require('underscore'); +var async = require('async'); +var _ = require('underscore'); -var db = require('../database'), - posts = require('../posts'), - topics = require('../topics'); +var db = require('../database'); +var posts = require('../posts'); +var topics = require('../topics'); module.exports = function(User) { User.getModerationHistory = function(uid, callback) { async.waterfall([ function(next) { async.parallel({ - flags: async.apply(db.getSortedSetRevRangeByScoreWithScores, 'uid:' + uid + ':flag:pids', 0, 20, '+inf', '-inf'), - bans: async.apply(db.getSortedSetRevRangeByScoreWithScores, 'uid:' + uid + ':bans', 0, 20, '+inf', '-inf') + flags: async.apply(db.getSortedSetRevRangeWithScores, 'uid:' + uid + ':flag:pids', 0, 19), + bans: async.apply(db.getSortedSetRevRangeWithScores, 'uid:' + uid + ':bans', 0,19) }, next); }, - async.apply(getFlagMetadata), - async.apply(formatBanData) + function(data, next) { + getFlagMetadata(data, next); + } ], function(err, data) { - callback(err, data); + if (err) { + return callback(err); + } + formatBanData(data); + callback(null, data); }); }; function getFlagMetadata(data, callback) { - // Retrieve post title & slug from flags list - posts.getPostsFields(data.flags.map(function(flagObj) { + var pids = data.flags.map(function(flagObj) { return parseInt(flagObj.value, 10); - }), ['tid'], function(err, postData) { + }); + + posts.getPostsFields(pids, ['tid'], function(err, postData) { if (err) { return callback(err); } @@ -37,6 +43,9 @@ module.exports = function(User) { }); topics.getTopicsFields(tids, ['title'], function(err, topicData) { + if (err) { + return callback(err); + } data.flags = data.flags.map(function(flagObj, idx) { flagObj.pid = flagObj.value; flagObj.timestamp = flagObj.score; @@ -54,7 +63,7 @@ module.exports = function(User) { }); } - function formatBanData(data, callback) { + function formatBanData(data) { data.bans = data.bans.map(function(banObj) { banObj.until = parseInt(banObj.value, 10); banObj.untilReadable = new Date(banObj.until).toString(); @@ -67,7 +76,5 @@ module.exports = function(User) { return banObj; }); - - setImmediate(callback, null, data); } -} \ No newline at end of file +}; \ No newline at end of file From c58e23db58f41d8d3e741d20d9ca35d02c0ad6b5 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Sun, 14 Aug 2016 19:12:33 +0300 Subject: [PATCH 56/63] fix tests --- src/groups.js | 1 + tests/categories.js | 2 +- tests/database/hash.js | 5 +---- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/groups.js b/src/groups.js index e572c30110..bd6e122d33 100644 --- a/src/groups.js +++ b/src/groups.js @@ -182,6 +182,7 @@ var utils = require('../public/src/utils'); results.base.deleted = !!parseInt(results.base.deleted, 10); results.base.hidden = !!parseInt(results.base.hidden, 10); results.base.system = !!parseInt(results.base.system, 10); + results.base.memberCount = parseInt(results.base.memberCount, 10); results.base.private = (results.base.private === null || results.base.private === undefined) ? true : !!parseInt(results.base.private, 10); results.base.disableJoinRequests = parseInt(results.base.disableJoinRequests, 10) === 1; results.base.isMember = results.isMember; diff --git a/tests/categories.js b/tests/categories.js index 4ec06ab3b4..c5bbee22cc 100644 --- a/tests/categories.js +++ b/tests/categories.js @@ -38,7 +38,7 @@ describe('Categories', function() { set: 'cid:' + categoryObj.cid + ':tids', reverse: true, start: 0, - end: -1, + stop: -1, uid: 0 }, function(err, categoryData) { assert(categoryData); diff --git a/tests/database/hash.js b/tests/database/hash.js index a178280e3c..7bcd23f5d8 100644 --- a/tests/database/hash.js +++ b/tests/database/hash.js @@ -202,10 +202,7 @@ describe('Hash methods', function() { assert.equal(err, null); assert.equal(arguments.length, 2); assert.equal(Array.isArray(values) && values.length === 3, true); - values.forEach(function(value) { - assert.notEqual(['baris', 'usakli', 99].indexOf(value), -1); - }); - + assert.deepEqual(['baris', 'usakli', 99].sort(), values.sort()); done(); }); }); From 49bf27d98548eafe804cfba78d882e3565a5bd09 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Sun, 14 Aug 2016 21:40:58 +0300 Subject: [PATCH 57/63] closes #4944 --- public/src/client/topic/fork.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/public/src/client/topic/fork.js b/public/src/client/topic/fork.js index 2083a4867e..ca30f157b0 100644 --- a/public/src/client/topic/fork.js +++ b/public/src/client/topic/fork.js @@ -4,9 +4,9 @@ define('forum/topic/fork', ['components', 'postSelect'], function(components, postSelect) { - var Fork = {}, - forkModal, - forkCommit; + var Fork = {}; + var forkModal; + var forkCommit; Fork.init = function() { $('.topic').on('click', '[component="topic/fork"]', onForkThreadClicked); @@ -95,7 +95,10 @@ define('forum/topic/fork', ['components', 'postSelect'], function(components, po components.get('post', 'pid', pid).toggleClass('bg-success', false); }); - forkModal.remove(); + if (forkModal) { + forkModal.remove(); + forkModal = null; + } components.get('topic').off('click', '[data-pid]'); postSelect.enableClicksOnPosts(); From 96abdb4b69b0848be1018e7c9e708fd25028d13a Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Mon, 15 Aug 2016 09:26:06 -0400 Subject: [PATCH 58/63] Up composer --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4d457b471a..d600e4661c 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "morgan": "^1.3.2", "mousetrap": "^1.5.3", "nconf": "~0.8.2", - "nodebb-plugin-composer-default": "4.1.7", + "nodebb-plugin-composer-default": "4.1.8", "nodebb-plugin-dbsearch": "1.0.2", "nodebb-plugin-emoji-extended": "1.1.1", "nodebb-plugin-emoji-one": "1.1.5", From b9961bcffa1721856af6a9336aa9a9da7dba07ae Mon Sep 17 00:00:00 2001 From: barisusakli Date: Mon, 15 Aug 2016 19:08:08 +0300 Subject: [PATCH 59/63] if email is undefined use empty string --- src/user/create.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/user/create.js b/src/user/create.js index bd79270a93..df504c3da4 100644 --- a/src/user/create.js +++ b/src/user/create.js @@ -26,7 +26,7 @@ module.exports = function(User) { var userData = { 'username': data.username, 'userslug': data.userslug, - 'email': data.email, + 'email': data.email || '', 'joindate': timestamp, 'lastonline': timestamp, 'picture': '', From 6022fd984a4169a2c259facc4645d2af9da683ee Mon Sep 17 00:00:00 2001 From: barisusakli Date: Mon, 15 Aug 2016 19:23:10 +0300 Subject: [PATCH 60/63] closes #4945 --- src/database/mongo/sorted.js | 80 ++++++++++++++++++++++++++ src/database/redis/sorted.js | 63 +++++++++++++++++++-- tests/database/sorted.js | 105 +++++++++++++++++++++++++++++++++++ 3 files changed, 243 insertions(+), 5 deletions(-) diff --git a/src/database/mongo/sorted.js b/src/database/mongo/sorted.js index 9e9f72969e..a262ff9984 100644 --- a/src/database/mongo/sorted.js +++ b/src/database/mongo/sorted.js @@ -595,4 +595,84 @@ module.exports = function(db, module) { callback ); }; + + + module.getSortedSetIntersect = function(params, callback) { + params.sort = 1; + getSortedSetRevIntersect(params, callback); + }; + + module.getSortedSetRevIntersect = function(params, callback) { + params.sort = -1; + getSortedSetRevIntersect(params, callback); + }; + + function getSortedSetRevIntersect (params, callback) { + var sets = params.sets; + var start = params.hasOwnProperty('start') ? params.start : 0; + var stop = params.hasOwnProperty('stop') ? params.stop : -1; + var weights = params.weights || []; + var aggregate = {}; + + if (params.aggregate) { + aggregate['$' + params.aggregate.toLowerCase()] = '$score'; + } else { + aggregate.$sum = '$score'; + } + + var limit = stop - start + 1; + if (limit <= 0) { + limit = 0; + } + + var pipeline = []; + + pipeline.push({ $match: { _key: {$in: sets}} }); + + weights.forEach(function(weight, index) { + if (weight !== 1) { + pipeline.push({ + $project: { + value: 1, + score: { + $cond: { if: { $eq: [ "$_key", sets[index] ] }, then: { $multiply: [ '$score', weight ] }, else: '$score' } + } + } + }); + } + }); + + pipeline.push({ $group: { _id: {value: '$value'}, totalScore: aggregate, count: {$sum: 1}} }); + pipeline.push({ $match: { count: sets.length} }); + pipeline.push({ $sort: { totalScore: params.sort} }); + + if (start) { + pipeline.push({ $skip: start }); + } + + if (limit > 0) { + pipeline.push({ $limit: limit }); + } + + var project = { _id: 0, value: '$_id.value'}; + if (params.withScores) { + project.score = '$totalScore'; + } + pipeline.push({ $project: project }); + + db.collection('objects').aggregate(pipeline, function(err, data) { + if (err || !data) { + return callback(err); + } + + if (!params.withScores) { + data = data.map(function(item) { + return item.value; + }); + } + + callback(null, data); + }); + } + }; diff --git a/src/database/redis/sorted.js b/src/database/redis/sorted.js index cd1587f494..d97b6b60cc 100644 --- a/src/database/redis/sorted.js +++ b/src/database/redis/sorted.js @@ -29,7 +29,7 @@ module.exports = function(redisClient, module) { args.push(scores[i], values[i]); } - redisClient.zadd(args, function(err, res) { + redisClient.zadd(args, function(err) { callback(err); }); } @@ -42,7 +42,7 @@ module.exports = function(redisClient, module) { multi.zadd(keys[i], score, value); } - multi.exec(function(err, res) { + multi.exec(function(err) { callback(err); }); }; @@ -53,13 +53,13 @@ module.exports = function(redisClient, module) { value = [value]; } - helpers.multiKeyValues(redisClient, 'zrem', key, value, function(err, result) { + helpers.multiKeyValues(redisClient, 'zrem', key, value, function(err) { callback(err); }); }; module.sortedSetsRemove = function(keys, value, callback) { - helpers.multiKeysValue(redisClient, 'zrem', keys, value, function(err, result) { + helpers.multiKeysValue(redisClient, 'zrem', keys, value, function(err) { callback(err); }); }; @@ -70,7 +70,7 @@ module.exports = function(redisClient, module) { for(var i=0; i Date: Mon, 15 Aug 2016 19:26:18 +0300 Subject: [PATCH 61/63] shorter --- src/database/mongo/sorted.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/database/mongo/sorted.js b/src/database/mongo/sorted.js index a262ff9984..1f9a67adb1 100644 --- a/src/database/mongo/sorted.js +++ b/src/database/mongo/sorted.js @@ -625,9 +625,7 @@ module.exports = function(db, module) { limit = 0; } - var pipeline = []; - - pipeline.push({ $match: { _key: {$in: sets}} }); + var pipeline = [{ $match: { _key: {$in: sets}} }]; weights.forEach(function(weight, index) { if (weight !== 1) { From 3d56776ab070f80c34367f0f5e4ad806b8e8c2b6 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Mon, 15 Aug 2016 19:28:01 +0300 Subject: [PATCH 62/63] fix tabs --- src/database/redis/sorted.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/database/redis/sorted.js b/src/database/redis/sorted.js index d97b6b60cc..eaa3b2430f 100644 --- a/src/database/redis/sorted.js +++ b/src/database/redis/sorted.js @@ -249,7 +249,7 @@ module.exports = function(redisClient, module) { params.push('WITHSCORES'); } - var multi = redisClient.multi(); + var multi = redisClient.multi(); multi.zunionstore([tempSetName, sets.length].concat(sets)); multi[method](params); multi.del(tempSetName); @@ -315,7 +315,7 @@ module.exports = function(redisClient, module) { rangeParams.push('WITHSCORES'); } - var multi = redisClient.multi(); + var multi = redisClient.multi(); multi.zinterstore(interParams); multi[params.method](rangeParams); multi.del(tempSetName); From ebbfe3cc1f21a60633f0b7c4d70124032a23519c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Mon, 15 Aug 2016 20:21:32 +0300 Subject: [PATCH 63/63] Update README.md --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 200a444b6d..2d1c90fed8 100644 --- a/README.md +++ b/README.md @@ -30,8 +30,10 @@ Additional functionality is enabled through the use of third-party plugins. [![](http://i.imgur.com/LmHtPhob.png)](http://i.imgur.com/LmHtPho.png) [![](http://i.imgur.com/paiJPJkb.jpg)](http://i.imgur.com/paiJPJk.jpg) -[![](http://i.imgur.com/8OLssij.png)](http://i.imgur.com/8OLssij.png) -[![](http://i.imgur.com/JKOc0LZ.png)](http://i.imgur.com/JKOc0LZ.png) +[![](http://i.imgur.com/HwNEXGu.png)](http://i.imgur.com/HwNEXGu.png) +[![](http://i.imgur.com/II1byYs.png)](http://i.imgur.com/II1byYs.png) + + ## How can I follow along/contribute?