[[admin/manage/ip-blacklist:lead]]
diff --git a/src/views/admin/manage/registration.tpl b/src/views/admin/manage/registration.tpl
index f8504fb31d..961d4863f7 100644
--- a/src/views/admin/manage/registration.tpl
+++ b/src/views/admin/manage/registration.tpl
@@ -1,109 +1,121 @@
-
\ No newline at end of file
diff --git a/src/views/admin/manage/tags.tpl b/src/views/admin/manage/tags.tpl
index d2b3310f81..41851df893 100644
--- a/src/views/admin/manage/tags.tpl
+++ b/src/views/admin/manage/tags.tpl
@@ -1,5 +1,4 @@
diff --git a/src/views/admin/manage/users.tpl b/src/views/admin/manage/users.tpl
index 356870d604..7d7fdbbe28 100644
--- a/src/views/admin/manage/users.tpl
+++ b/src/views/admin/manage/users.tpl
@@ -71,37 +71,41 @@
From aea40902b01db62159b3780f4f84ca17e82b4f45 Mon Sep 17 00:00:00 2001
From: pichalite
Date: Thu, 23 Feb 2017 00:28:54 +0000
Subject: [PATCH 17/22] Fix markup in category privileges template
---
.../admin/partials/categories/privileges.tpl | 196 +++++++++---------
1 file changed, 102 insertions(+), 94 deletions(-)
diff --git a/src/views/admin/partials/categories/privileges.tpl b/src/views/admin/partials/categories/privileges.tpl
index f15d207d6c..2ec8fa2026 100644
--- a/src/views/admin/partials/categories/privileges.tpl
+++ b/src/views/admin/partials/categories/privileges.tpl
@@ -1,101 +1,109 @@
-
-
- [[admin/manage/categories:privileges.section-user]] |
-
- {privileges.labels.users.name} |
-
-
-
-
-
-
-
-
-
- {../icon:text}
-
- |
- {privileges.users.username} |
- {function.spawnPrivilegeStates, privileges.users.username, privileges}
-
-
-
-
-
- |
-
-
-
-
- [[admin/manage/categories:privileges.no-users]]
-
- |
-
-
+
+
+
+ [[admin/manage/categories:privileges.section-user]] |
+
+ {privileges.labels.users.name} |
+
+
+
+
+
+
+
+
+
+
+
+ {../icon:text}
+
+ |
+ {privileges.users.username} |
+ {function.spawnPrivilegeStates, privileges.users.username, privileges}
+
+
+
+
+
+ |
+
+
+
+
+ [[admin/manage/categories:privileges.no-users]]
+
+ |
+
+
+
-
-
- [[admin/manage/categories:privileges.section-group]] |
-
- {privileges.labels.groups.name} |
-
-
-
-
-
-
-
-
- {privileges.groups.name}
- |
- |
- {function.spawnPrivilegeStates, name, privileges}
-
-
-
-
-
-
-
-
-
- |
-
+
+
+
+ [[admin/manage/categories:privileges.section-group]] |
+
+ {privileges.labels.groups.name} |
+
+
+
+
+
+
+
+
+
+
+ {privileges.groups.name}
+ |
+ |
+ {function.spawnPrivilegeStates, name, privileges}
+
+
+
+
+
+
+
+
+
+ |
+
+
[[admin/manage/categories:privileges.inherit]]
From 02cc988ae7c8dc0db0a46411e3ea0617e51aa500 Mon Sep 17 00:00:00 2001
From: "Misty (Bot)"
Date: Thu, 23 Feb 2017 09:22:14 +0000
Subject: [PATCH 18/22] Latest translations and fallbacks
---
public/language/ja/unread.json | 2 +-
public/language/ru/admin/advanced/cache.json | 10 +++++-----
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/public/language/ja/unread.json b/public/language/ja/unread.json
index 47909bf086..feaef7879f 100644
--- a/public/language/ja/unread.json
+++ b/public/language/ja/unread.json
@@ -1,6 +1,6 @@
{
"title": "未読",
- "no_unread_topics": "未読のスレッドがあります。",
+ "no_unread_topics": "未読のスレッドはありません。",
"load_more": "もっと見る",
"mark_as_read": "既読にする",
"selected": "選択済み",
diff --git a/public/language/ru/admin/advanced/cache.json b/public/language/ru/admin/advanced/cache.json
index 208775f991..c0487f399b 100644
--- a/public/language/ru/admin/advanced/cache.json
+++ b/public/language/ru/admin/advanced/cache.json
@@ -1,11 +1,11 @@
{
"post-cache": "Кэш записи",
"posts-in-cache": "Записей в кэше",
- "average-post-size": "Average Post Size",
- "length-to-max": "Length / Max",
+ "average-post-size": "Средний размер записи",
+ "length-to-max": "Длина / Максимальная",
"percent-full": "%1% Full",
- "post-cache-size": "Post Cache Size",
+ "post-cache-size": "Размер записи в кэше",
"items-in-cache": "Items in Cache",
- "control-panel": "Control Panel",
- "update-settings": "Update Cache Settings"
+ "control-panel": "Панель управления",
+ "update-settings": "Обновить настройки кэша"
}
\ No newline at end of file
From 4cd4414d197046c0434834a19f6d683f6ac5c0e7 Mon Sep 17 00:00:00 2001
From: barisusakli
Date: Thu, 23 Feb 2017 15:29:35 +0300
Subject: [PATCH 19/22] small change
---
src/meta/blacklist.js | 2 +-
src/meta/js.js | 42 ++++++++++++++++++------------------------
2 files changed, 19 insertions(+), 25 deletions(-)
diff --git a/src/meta/blacklist.js b/src/meta/blacklist.js
index c02f6fb198..a078b89815 100644
--- a/src/meta/blacklist.js
+++ b/src/meta/blacklist.js
@@ -44,8 +44,8 @@ Blacklist.save = function (rules, callback) {
db.set('ip-blacklist-rules', rules, next);
},
function (next) {
+ Blacklist.load(next);
pubsub.publish('blacklist:reload');
- next();
}
], callback);
};
diff --git a/src/meta/js.js b/src/meta/js.js
index 969239f0a8..90f757361a 100644
--- a/src/meta/js.js
+++ b/src/meta/js.js
@@ -129,10 +129,10 @@ module.exports = function (Meta) {
});
}, callback);
};
-
+
function linkModules(callback) {
var modules = Meta.js.scripts.modules;
-
+
async.eachLimit(Object.keys(modules), 1000, function (relPath, next) {
var filePath = path.join(__dirname, '../../', modules[relPath]);
var destPath = path.join(__dirname, '../../build/public/src/modules', relPath);
@@ -177,41 +177,35 @@ module.exports = function (Meta) {
next();
});
}, function (err) {
- if (err) {
- return callback(err);
- }
-
- callback(null, modules);
+ callback(err, modules);
});
}
-
+
function clearModules(callback) {
var builtPaths = moduleDirs.map(function (p) {
return '../../build/public/src/' + p;
});
async.each(builtPaths, function (builtPath, next) {
rimraf(path.join(__dirname, builtPath), next);
- }, callback);
+ }, function (err) {
+ callback(err);
+ });
}
Meta.js.buildModules = function (callback) {
- clearModules(function (err) {
- if (err) {
- return callback(err);
- }
-
- if (global.env === 'development') {
- return linkModules(callback);
- }
-
- getModuleList(function (err, modules) {
- if (err) {
- return callback(err);
+ async.waterfall([
+ clearModules,
+ function (next) {
+ if (global.env === 'development') {
+ return linkModules(callback);
}
- minifyModules(modules, callback);
- });
- });
+ getModuleList(next);
+ },
+ function (modules, next) {
+ minifyModules(modules, next);
+ }
+ ], callback);
};
Meta.js.linkStatics = function (callback) {
From 09d0ce4778b3d61246718f1253f5f75fbdfcc74d Mon Sep 17 00:00:00 2001
From: barisusakli
Date: Thu, 23 Feb 2017 17:02:54 +0300
Subject: [PATCH 20/22] post tests
---
src/socket.io/posts.js | 33 +++++-----
test/posts.js | 138 +++++++++++++++++++++++++++++++++++++++++
test/topics.js | 7 +++
3 files changed, 162 insertions(+), 16 deletions(-)
diff --git a/src/socket.io/posts.js b/src/socket.io/posts.js
index fe729a5c11..6b1e5ce71b 100644
--- a/src/socket.io/posts.js
+++ b/src/socket.io/posts.js
@@ -31,25 +31,26 @@ SocketPosts.reply = function (socket, data, callback) {
data.req = websockets.reqFromSocket(socket);
data.timestamp = Date.now();
- topics.reply(data, function (err, postData) {
- if (err) {
- return callback(err);
- }
-
- var result = {
- posts: [postData],
- 'reputation:disabled': parseInt(meta.config['reputation:disabled'], 10) === 1,
- 'downvote:disabled': parseInt(meta.config['downvote:disabled'], 10) === 1,
- };
+ async.waterfall([
+ function (next) {
+ topics.reply(data, next);
+ },
+ function (postData, next) {
+ var result = {
+ posts: [postData],
+ 'reputation:disabled': parseInt(meta.config['reputation:disabled'], 10) === 1,
+ 'downvote:disabled': parseInt(meta.config['downvote:disabled'], 10) === 1,
+ };
- callback(null, postData);
+ next(null, postData);
- websockets.in('uid_' + socket.uid).emit('event:new_post', result);
+ websockets.in('uid_' + socket.uid).emit('event:new_post', result);
- user.updateOnlineUsers(socket.uid);
+ user.updateOnlineUsers(socket.uid);
- socketHelpers.notifyNew(socket.uid, 'newPost', result);
- });
+ socketHelpers.notifyNew(socket.uid, 'newPost', result);
+ }
+ ], callback);
};
SocketPosts.getRawPost = function (socket, pid, callback) {
@@ -120,7 +121,7 @@ SocketPosts.getPidIndex = function (socket, data, callback) {
SocketPosts.getReplies = function (socket, pid, callback) {
if (!utils.isNumber(pid)) {
- return callback(new Error('[[error:invalid-data]'));
+ return callback(new Error('[[error:invalid-data]]'));
}
var postPrivileges;
async.waterfall([
diff --git a/test/posts.js b/test/posts.js
index 84b5934724..42ebbde345 100644
--- a/test/posts.js
+++ b/test/posts.js
@@ -755,6 +755,144 @@ describe('Post\'s', function () {
});
});
+ describe('socket methods', function () {
+
+ var pid;
+ before(function (done) {
+ topics.reply({
+ uid: voterUid,
+ tid: topicData.tid,
+ timestamp: Date.now(),
+ content: 'raw content'
+ }, function (err, postData) {
+ assert.ifError(err);
+ pid = postData.pid;
+ privileges.categories.rescind(['read'], cid, 'guests', done);
+ });
+ });
+
+ var socketPosts = require('../src/socket.io/posts');
+ it('should error with invalid data', function (done) {
+ socketPosts.reply({uid: 0}, null, function (err) {
+ assert.equal(err.message, '[[error:invalid-data]]');
+ done();
+ });
+ });
+
+ it('should error with invalid tid', function (done) {
+ socketPosts.reply({uid: 0}, {tid: 0, content: 'derp'}, function (err) {
+ assert.equal(err.message, '[[error:invalid-data]]');
+ done();
+ });
+ });
+
+ it('should fail to get raw post because of privilege', function (done) {
+ socketPosts.getRawPost({uid: 0}, pid, function (err) {
+ assert.equal(err.message, '[[error:no-privileges]]');
+ done();
+ });
+ });
+
+ it('should fail to get raw post because post is deleted', function (done) {
+ posts.setPostField(pid, 'deleted', 1, function (err) {
+ assert.ifError(err);
+ socketPosts.getRawPost({uid: voterUid}, pid, function (err) {
+ assert.equal(err.message, '[[error:no-post]]');
+ done();
+ });
+ });
+ });
+
+ it('should get raw post content', function (done) {
+ posts.setPostField(pid, 'deleted', 0, function (err) {
+ assert.ifError(err);
+ socketPosts.getRawPost({uid: voterUid}, pid, function (err, postContent) {
+ assert.ifError(err);
+ assert.equal(postContent, 'raw content');
+ done();
+ });
+ });
+ });
+
+ it('should get post', function (done) {
+ socketPosts.getPost({uid: voterUid}, pid, function (err, postData) {
+ assert.ifError(err);
+ assert(postData);
+ done();
+ });
+ });
+
+ it('shold error with invalid data', function (done) {
+ socketPosts.loadMoreBookmarks({uid: voterUid}, {uid: voterUid, after: null}, function (err, postData) {
+ assert.equal(err.message, '[[error:invalid-data]]');
+ done();
+ });
+ });
+
+ it('should load more bookmarks', function (done) {
+ socketPosts.loadMoreBookmarks({uid: voterUid}, {uid: voterUid, after: 0}, function (err, data) {
+ assert.ifError(err);
+ assert(data);
+ done();
+ });
+ });
+
+ it('should load more user posts', function (done) {
+ socketPosts.loadMoreUserPosts({uid: voterUid}, {uid: voterUid, after: 0}, function (err, data) {
+ assert.ifError(err);
+ assert(data);
+ done();
+ });
+ });
+
+ it('should load more best posts', function (done) {
+ socketPosts.loadMoreBestPosts({uid: voterUid}, {uid: voterUid, after: 0}, function (err, data) {
+ assert.ifError(err);
+ assert(data);
+ done();
+ });
+ });
+
+ it('should load more up voted posts', function (done) {
+ socketPosts.loadMoreUpVotedPosts({uid: voterUid}, {uid: voterUid, after: 0}, function (err, data) {
+ assert.ifError(err);
+ assert(data);
+ done();
+ });
+ });
+
+ it('should load more down voted posts', function (done) {
+ socketPosts.loadMoreDownVotedPosts({uid: voterUid}, {uid: voterUid, after: 0}, function (err, data) {
+ assert.ifError(err);
+ assert(data);
+ done();
+ });
+ });
+
+ it('should get post category', function (done) {
+ socketPosts.getCategory({uid: voterUid}, pid, function (err, postCid) {
+ assert.ifError(err);
+ assert.equal(cid, postCid);
+ done();
+ });
+ });
+
+ it('should error with invalid data', function (done) {
+ socketPosts.getPidIndex({uid: voterUid}, null, function (err) {
+ assert.equal(err.message, '[[error:invalid-data]]');
+ done();
+ });
+ });
+
+ it('should get pid index', function (done) {
+ socketPosts.getPidIndex({uid: voterUid}, {pid: pid, tid: topicData.tid, topicPostSort: 'oldest-to-newest'}, function (err, index) {
+ assert.ifError(err);
+ assert.equal(index, 2);
+ done();
+ });
+ });
+ });
+
after(function (done) {
db.emptydb(done);
});
diff --git a/test/topics.js b/test/topics.js
index 01af1f5f2e..1ade4de261 100644
--- a/test/topics.js
+++ b/test/topics.js
@@ -130,6 +130,13 @@ describe('Topic\'s', function () {
});
});
+ it('should error if pid is not a number', function (done) {
+ socketPosts.getReplies({uid: 0}, 'abc', function (err) {
+ assert.equal(err.message, '[[error:invalid-data]]');
+ done();
+ });
+ });
+
it('should fail to create new reply with invalid user id', function (done) {
topics.reply({uid: null, content: 'test post', tid: newTopic.tid}, function (err) {
assert.equal(err.message, '[[error:no-privileges]]');
From 0de21cb3ffdb63fa1a95324396624940086805ea Mon Sep 17 00:00:00 2001
From: barisusakli
Date: Thu, 23 Feb 2017 17:12:46 +0300
Subject: [PATCH 21/22] fix tab
---
src/socket.io/posts.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/socket.io/posts.js b/src/socket.io/posts.js
index 6b1e5ce71b..8ded335780 100644
--- a/src/socket.io/posts.js
+++ b/src/socket.io/posts.js
@@ -1,6 +1,6 @@
"use strict";
-var async = require('async');
+var async = require('async');
var posts = require('../posts');
var privileges = require('../privileges');
From d4c2fc3bc8f5b96feb932d17169820746e025be1 Mon Sep 17 00:00:00 2001
From: Julian Lam
Date: Thu, 23 Feb 2017 11:54:46 -0500
Subject: [PATCH 22/22] closes #5472
---
src/socket.io/index.js | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/src/socket.io/index.js b/src/socket.io/index.js
index 58e31a78ea..f4732d9d9e 100644
--- a/src/socket.io/index.js
+++ b/src/socket.io/index.js
@@ -33,6 +33,28 @@ Sockets.init = function (server) {
io.on('connection', onConnection);
+ /*
+ * Restrict socket.io listener to cookie domain. If none is set, infer based on url.
+ * Production only so you don't get accidentally locked out.
+ * Can be overridden via config (socket.io:origins)
+ */
+ if (process.env.NODE_ENV !== 'development') {
+ var domain = nconf.get('cookieDomain');
+ var parsedUrl = url.parse(nconf.get('url'));
+ var override = nconf.get('socket.io:origins');
+ if (!domain) {
+ domain = parsedUrl.hostname; // cookies don't provide isolation by port: http://stackoverflow.com/a/16328399/122353
+ }
+
+ if (!override) {
+ io.set('origins', parsedUrl.protocol + '//' + domain + ':*');
+ winston.info('[socket.io] Restricting access to origin: ' + parsedUrl.protocol + '//' + domain + ':*');
+ } else {
+ io.set('origins', override);
+ winston.info('[socket.io] Restricting access to origin: ' + override);
+ }
+ }
+
io.listen(server, {
transports: nconf.get('socket.io:transports')
});