diff --git a/CHANGELOG.md b/CHANGELOG.md
index 00db835f26..c7359fd095 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,87 @@
+#### 1.12.2 (2019-05-15)
+
+##### Chores
+
+* incrementing version number - v1.12.2 (22db818e)
+* bump themes #7576 (d349754d)
+* bump themes (59bdc970)
+* bump themes (abcca134)
+* bump themes (551b18cd)
+* incrementing version number - v1.12.1 (dd973abe)
+* **deps:**
+ * update dependency lint-staged to v8.1.7 (dc6b49ca)
+ * update commitlint monorepo (9998e86b)
+ * update dependency jsdom to v15.1.0 (fcd6dc88)
+ * update dependency mocha to v6.1.4 (3ff8154b)
+ * update node:8.16.0 docker digest to b5484d1 (6421f10f)
+ * update dependency husky to v2.3.0 (c20e3313)
+ * update dependency nyc to v14.1.1 (#7584) (9047210c)
+ * update dependency eslint to v5.16.0 (692e2ead)
+ * update dependency nyc to v14 (9210baf5)
+ * update dependency husky to v2.2.0 (8a018a5f)
+ * update dependency lint-staged to v8.1.6 (4e39caf8)
+ * update dependency husky to v2.1.0 (65ff0bbd)
+ * update dependency husky to v2 (e81a1dbb)
+ * update dependency eslint-plugin-import to v2.17.2 (#7546) (c1fb17f9)
+ * update dependency jsdom to v15 (#7556) (d4d8d98f)
+ * update dependency jsdom to v14.1.0 (#7555) (ca694fd1)
+ * update node.js to v8.16.0 (#7554) (f10708e7)
+ * update dependency eslint-plugin-import to v2.17.1 (69dd8e4d)
+ * update dependency mocha to v6.1.2 (b7169772)
+
+##### Documentation Changes
+
+* updated changelog (93b688d0)
+
+##### New Features
+
+* let theme know downvoting is disabled, closes https://github.com/NodeBB/NodeBB/pull/7568 (bd94fbc2)
+* closes #7583 (cf5aeace)
+* #7319 (9385c8e3)
+* add node12 to travis (1a7036a6)
+* allow file uploading on registration interstitial (ddffc904)
+* #7527 (ba5e1eaa)
+* #7515 (c38db4f7)
+
+##### Bug Fixes
+
+* #7599 image size measurement erroring out on missing path (0d86781c)
+* #7590 updated chat and post edit and delete timeout labels in ACP (4f0dc443)
+* tests (3a7e99a5)
+* #7586, switchTimeagoLanguage shouldn't discriminate against languages w/o shorthands (1703233f)
+* #7576 "Disable password changes" can be sidestepped (50260e13)
+* if editing password is disabled in ACP, prevent direct access via route/socket (related: #7576) (e114b16d)
+* #7582 (c9ca72d0)
+* #7461 (96cb29aa)
+* increase batch size (3d938e7b)
+* #7564 (bf6fc502)
+* group cover upload not working for s3 upload (#7571) (8945ebcb)
+* test (b9903120)
+* #7539 (c940a733)
+* #7565 (07e9b67e)
+* #7464 (32cf07d7)
+* #7147 (fe6d64cc)
+* #7424 (f86d74d8)
+* #7562 (09681e6c)
+* node12 tests (8775e7e6)
+* add post queue to /compose POST route (c6cd6c57)
+* remove redis object cache (4df925e7)
+* #7545 (74038849)
+* failing test from 00552d7183f0416a0caa113fe2f1e658659648f7 (9bf3517d)
+* fire filter:register.complete for users approved via registration queue (00552d71)
+* #7540 (8778f00b)
+* more graceful error handling and output for cli/reset (d3ebda73)
+* #6438 only apply whitelist when fields request empty (#7528) (808c4909)
+* **deps:**
+ * update dependency nodebb-theme-vanilla to v10.1.31 (#7589) (a9f9d19b)
+ * update dependency nodebb-theme-persona to v9.1.36 (#7588) (bd86e58d)
+ * update dependency mongodb to v3.2.4 (#7581) (26d6d0be)
+ * update dependency postcss to v7.0.16 (10a47a29)
+ * update dependency nodebb-theme-persona to v9.1.33 (#7563) (7c4201f2)
+ * update dependency sharp to v0.22.1 (#7561) (288a25f0)
+ * update dependency nodebb-plugin-composer-default to v6.2.12 (#7538) (a54f8f00)
+ * update dependency mongodb to v3.2.3 (97a7f02f)
+
#### 1.12.1 (2019-04-10)
##### Chores
diff --git a/install/package.json b/install/package.json
index b8916c86b1..a434991d2f 100644
--- a/install/package.json
+++ b/install/package.json
@@ -2,7 +2,7 @@
"name": "nodebb",
"license": "GPL-3.0",
"description": "NodeBB Forum",
- "version": "1.12.1",
+ "version": "1.12.2",
"homepage": "http://www.nodebb.org",
"repository": {
"type": "git",
@@ -142,7 +142,7 @@
"grunt-contrib-watch": "1.1.0",
"husky": "2.3.0",
"jsdom": "15.1.0",
- "lint-staged": "8.1.6",
+ "lint-staged": "8.1.7",
"mocha": "6.1.4",
"mocha-lcov-reporter": "1.3.0",
"nyc": "14.1.1",
diff --git a/public/language/en-GB/admin/manage/categories.json b/public/language/en-GB/admin/manage/categories.json
index 7e49aef36b..1eda6ea080 100644
--- a/public/language/en-GB/admin/manage/categories.json
+++ b/public/language/en-GB/admin/manage/categories.json
@@ -45,7 +45,12 @@
"privileges.search-group": "Add Group",
"privileges.copy-to-children": "Copy to Children",
"privileges.copy-from-category": "Copy from Category",
+ "privileges.copy-privileges-to-all-categories": "Copy to All Categories",
+ "privileges.copy-group-privileges-to-children": "Copy this group's privileges to the children of this category.",
+ "privileges.copy-group-privileges-to-all-categories": "Copy this group's privileges to all categories.",
+ "privileges.copy-group-privileges-from": "Copy this group's privileges from another category.",
"privileges.inherit": "If the registered-users
group is granted a specific privilege, all other groups receive an implicit privilege, even if they are not explicitly defined/checked. This implicit privilege is shown to you because all users are part of the registered-users
user group, and so, privileges for additional groups need not be explicitly granted.",
+ "privileges.copy-success": "Privileges copied!",
"analytics.back": "Back to Categories List",
"analytics.title": "Analytics for \"%1\" category",
diff --git a/public/language/en-GB/email.json b/public/language/en-GB/email.json
index f8a083bebd..23fd34025d 100644
--- a/public/language/en-GB/email.json
+++ b/public/language/en-GB/email.json
@@ -18,7 +18,7 @@
"invitation.text1": "%1 has invited you to join %2",
"invitation.text2": "Your invitation will expire in %1 days.",
- "invitation.ctr": "Click here to create your account.",
+ "invitation.cta": "Click here to create your account.",
"reset.text1": "We received a request to reset your password, possibly because you have forgotten it. If this is not the case, please ignore this email.",
"reset.text2": "To continue with the password reset, please click on the following link:",
@@ -37,14 +37,13 @@
"digest.subject": "Digest for %1",
"digest.title": "Your Daily Digest",
- "notif.chat.subject": "New chat message received from %1",
- "notif.chat.cta": "Click here to continue the conversation",
- "notif.chat.unsub.info": "This chat notification was sent to you due to your subscription settings.",
-
- "notif.post.cta": "Click here to read the full topic",
"notif.post.unsub.info": "This post notification was sent to you due to your subscription settings.",
- "notif.cta": "Click here to go to forum",
+ "notif.cta": "To the forum",
+ "notif.cta-new-reply": "View Post",
+ "notif.cta-new-chat": "View Chat",
+ "notif.test.short": "Testing Notifications",
+ "notif.test.long": "This is a test of the notifications email. Send help!",
"test.text1": "This is a test email to verify that the emailer is set up correctly for your NodeBB.",
diff --git a/public/language/pl/admin/development/info.json b/public/language/pl/admin/development/info.json
index aa9e025623..1cf80f089f 100644
--- a/public/language/pl/admin/development/info.json
+++ b/public/language/pl/admin/development/info.json
@@ -7,8 +7,8 @@
"online": "dostępny",
"git": "git",
"memory": "pamięć",
- "load": "system load",
- "cpu-usage": "cpu usage",
+ "load": "obciążenie systemu",
+ "cpu-usage": "użycie procesora",
"uptime": "czas działania",
"registered": "Zarejestrowane",
diff --git a/public/language/pl/admin/manage/groups.json b/public/language/pl/admin/manage/groups.json
index 45241f5e4b..056e7a5c8d 100644
--- a/public/language/pl/admin/manage/groups.json
+++ b/public/language/pl/admin/manage/groups.json
@@ -1,12 +1,12 @@
{
"name": "Nazwa grupy",
"badge": "Badge",
- "properties": "Properties",
+ "properties": "Właściwości",
"description": "Opis grupy",
"member-count": "Liczba użytkowników",
"system": "System",
- "hidden": "Hidden",
- "private": "Private",
+ "hidden": "Ukryty",
+ "private": "Prywatny",
"edit": "Edytuj",
"search-placeholder": "Szukaj",
"create": "Utwórz grupę",
@@ -21,7 +21,7 @@
"edit.user-title": "Tytuł członków ",
"edit.icon": "Ikona grupy",
"edit.label-color": "Kolor etykiety grupy",
- "edit.text-color": "Group Text Color",
+ "edit.text-color": "Kolor Tekstu Grupy",
"edit.show-badge": "Pokaż etykietę",
"edit.private-details": "Jeśli włączone, przystępowanie do grup wymaga zatwierdzenia przez właściciela grupy",
"edit.private-override": "Ostrzeżenie: Prywatne grupy są wyłączone w ustawieniach, co powoduje przesłonięcia opcji.",
diff --git a/public/language/ru/admin/advanced/database.json b/public/language/ru/admin/advanced/database.json
index f1ad2d7ed8..3056b72870 100644
--- a/public/language/ru/admin/advanced/database.json
+++ b/public/language/ru/admin/advanced/database.json
@@ -18,17 +18,17 @@
"mongo.resident-memory": "Долгосрочная память",
"mongo.virtual-memory": "Виртуальная память",
"mongo.mapped-memory": "Расширенная память",
- "mongo.bytes-in": "Bytes In",
- "mongo.bytes-out": "Bytes Out",
- "mongo.num-requests": "Number of Requests",
+ "mongo.bytes-in": "Байт входящих",
+ "mongo.bytes-out": "Байт исходящих",
+ "mongo.num-requests": "Количество запросов",
"mongo.raw-info": "Сырые данные о MongoDB",
- "mongo.unauthorized": "NodeBB was unable to query the MongoDB database for relevant statistics. Please ensure that the user in use by NodeBB contains the "clusterMonitor" role for the "admin" database.",
+ "mongo.unauthorized": "NodeBB не смог создать запрос к базе данных MongoDB соответствующей статистики. Пожалуйста убедитесь, что пользователь, используемый NodeBB имеет "clusterMonitor" привилегию для "admin" базы данных. ",
"redis": "Redis",
"redis.version": "Версия Redis",
- "redis.keys": "Keys",
- "redis.expires": "Expires",
- "redis.avg-ttl": "Average TTL",
+ "redis.keys": "Ключей",
+ "redis.expires": "Истекает",
+ "redis.avg-ttl": "Средний TTL",
"redis.connected-clients": "Подключенные клиенты",
"redis.connected-slaves": "Подключенные устройства",
"redis.blocked-clients": "Заблокированные клиенты",
@@ -37,10 +37,10 @@
"redis.total-connections-recieved": "Общее число подключений получено",
"redis.total-commands-processed": "Команд обработано в общем",
"redis.iops": "Мгновенные операции. в секунду",
- "redis.iinput": "Instantaneous Input Per Second",
- "redis.ioutput": "Instantaneous Output Per Second",
- "redis.total-input": "Total Input",
- "redis.total-output": "Total Ouput",
+ "redis.iinput": "Текущих входящих в секунду",
+ "redis.ioutput": "Текущих исходящих в секунду",
+ "redis.total-input": "Всего входящих",
+ "redis.total-output": "Всего исходящих",
"redis.keyspace-hits": "Количество ключевых просмотров",
"redis.keyspace-misses": "Количество не ключевых просмотров",
diff --git a/public/language/ru/admin/development/info.json b/public/language/ru/admin/development/info.json
index 674fcee21c..b0a0962b8b 100644
--- a/public/language/ru/admin/development/info.json
+++ b/public/language/ru/admin/development/info.json
@@ -7,8 +7,8 @@
"online": "онлайн",
"git": "git",
"memory": "память",
- "load": "system load",
- "cpu-usage": "cpu usage",
+ "load": "системная загрузка",
+ "cpu-usage": "Использование процессора",
"uptime": "время работы",
"registered": "Зарегистрированных",
diff --git a/public/language/ru/admin/general/dashboard.json b/public/language/ru/admin/general/dashboard.json
index b1ceeed387..b841ef0344 100644
--- a/public/language/ru/admin/general/dashboard.json
+++ b/public/language/ru/admin/general/dashboard.json
@@ -65,9 +65,9 @@
"high-presence-topics": "Популярные темы",
"graphs.page-views": "Просмотров",
- "graphs.page-views-registered": "Page Views Registered",
- "graphs.page-views-guest": "Page Views Guest",
- "graphs.page-views-bot": "Page Views Bot",
+ "graphs.page-views-registered": "Зарегистрировано просмотров",
+ "graphs.page-views-guest": "Просмотров гостей",
+ "graphs.page-views-bot": "Просмотров ботов",
"graphs.unique-visitors": "Уникальных пользователей",
"graphs.registered-users": "Зарегистрированных пользователей",
"graphs.anonymous-users": "Анонимных пользователей",
diff --git a/public/language/ru/admin/general/navigation.json b/public/language/ru/admin/general/navigation.json
index 4f0a6caa30..2fee361bf4 100644
--- a/public/language/ru/admin/general/navigation.json
+++ b/public/language/ru/admin/general/navigation.json
@@ -5,11 +5,11 @@
"tooltip": "Подсказка:",
"text": "Текст:",
"text-class": "Класс текста: опциоально",
- "class": "Class: optional",
+ "class": "Класс: опционально",
"id": "ID: опциоанально",
"properties": "Свойства:",
- "groups": "Groups:",
+ "groups": "Группы:",
"open-new-window": "Открывать в новом окне",
"btn.delete": "Удалить",
diff --git a/public/language/ru/admin/manage/categories.json b/public/language/ru/admin/manage/categories.json
index b24f8d97d4..36698f8ad3 100644
--- a/public/language/ru/admin/manage/categories.json
+++ b/public/language/ru/admin/manage/categories.json
@@ -17,7 +17,7 @@
"parent-category": "Родительская категория",
"optional-parent-category": "(не обязательно) Родительская категория\n",
"parent-category-none": "(Пусто)",
- "copy-parent": "Copy Parent",
+ "copy-parent": "Скопировать Родительский",
"copy-settings": "Копировать настройки из",
"optional-clone-settings": "(не обязательно) Копировать настройки из",
"clone-children": "Дублировать вложенные категориии настройки",
@@ -30,13 +30,13 @@
"select-category": "Указать категорию",
"set-parent-category": "Указать родительскую категорию",
- "privileges.description": "You can configure the access control privileges for portions of the site in this section. Privileges can be granted on a per-user or a per-group basis. Select the domain of effect from the dropdown below.",
- "privileges.category-selector": "Configuring privileges for ",
+ "privileges.description": "В этой секции вы можете настроить права на управление доступом. Права могут быть предоставлены как на пользователя, так и на группу. Выберите применяемый домен с помощью формы поиска ниже.",
+ "privileges.category-selector": "Настройка привилегий для",
"privileges.warning": "Замечание: Настройки прав применяются немедленно. Нет необходимости сохранять категорию после изменения настроек.",
"privileges.section-viewing": "Права на просмотр",
"privileges.section-posting": "Права на создание поста",
"privileges.section-moderation": "Права модераторов",
- "privileges.section-other": "Other",
+ "privileges.section-other": "Другое",
"privileges.section-user": "Пользователь",
"privileges.search-user": "Добавить пользователя",
"privileges.no-users": "В этой категории нет специально заданных прав пользователя.",
diff --git a/public/language/ru/admin/manage/uploads.json b/public/language/ru/admin/manage/uploads.json
index 21bc8201fc..9d3b76a0c8 100644
--- a/public/language/ru/admin/manage/uploads.json
+++ b/public/language/ru/admin/manage/uploads.json
@@ -1,9 +1,9 @@
{
- "upload-file": "Upload File",
- "filename": "Filename",
+ "upload-file": "Загрузить Файл",
+ "filename": "Имя файла",
"usage": "Post Usage",
- "orphaned": "Orphaned",
- "size/filecount": "Size / Filecount",
- "confirm-delete": "Do you really want to delete this file?",
- "filecount": "%1 files"
+ "orphaned": "Отделенный",
+ "size/filecount": "Размер / Файлов",
+ "confirm-delete": "Вы действительно хотите удалить этот файл?",
+ "filecount": "%1 файлов"
}
\ No newline at end of file
diff --git a/public/language/ru/notifications.json b/public/language/ru/notifications.json
index f3b479299a..b9ae7b8e87 100644
--- a/public/language/ru/notifications.json
+++ b/public/language/ru/notifications.json
@@ -8,7 +8,7 @@
"outgoing_link_message": "Вы сейчас читаете: %1",
"continue_to": "Перейти на %1",
"return_to": "Вернуться к %1",
- "new_notification": "You have a new notification",
+ "new_notification": "У вас новое уведомление",
"you_have_unread_notifications": "У вас есть непрочитанные уведомления.",
"all": "Все",
"topics": "Темы",
diff --git a/public/src/admin/manage/privileges.js b/public/src/admin/manage/privileges.js
index f43ebef04f..86b2351d36 100644
--- a/public/src/admin/manage/privileges.js
+++ b/public/src/admin/manage/privileges.js
@@ -49,8 +49,29 @@ define('admin/manage/privileges', [
$('.privilege-table-container').on('click', '[data-action="search.user"]', Privileges.addUserToPrivilegeTable);
$('.privilege-table-container').on('click', '[data-action="search.group"]', Privileges.addGroupToPrivilegeTable);
- $('.privilege-table-container').on('click', '[data-action="copyToChildren"]', Privileges.copyPrivilegesToChildren);
- $('.privilege-table-container').on('click', '[data-action="copyPrivilegesFrom"]', Privileges.copyPrivilegesFromCategory);
+ $('.privilege-table-container').on('click', '[data-action="copyToChildren"]', function () {
+ Privileges.copyPrivilegesToChildren(cid, '');
+ });
+ $('.privilege-table-container').on('click', '[data-action="copyToChildrenGroup"]', function () {
+ var groupName = $(this).parents('[data-group-name]').attr('data-group-name');
+ Privileges.copyPrivilegesToChildren(cid, groupName);
+ });
+
+ $('.privilege-table-container').on('click', '[data-action="copyPrivilegesFrom"]', function () {
+ Privileges.copyPrivilegesFromCategory(cid, '');
+ });
+ $('.privilege-table-container').on('click', '[data-action="copyPrivilegesFromGroup"]', function () {
+ var groupName = $(this).parents('[data-group-name]').attr('data-group-name');
+ Privileges.copyPrivilegesFromCategory(cid, groupName);
+ });
+
+ $('.privilege-table-container').on('click', '[data-action="copyToAll"]', function () {
+ Privileges.copyPrivilegesToAllCategories(cid, '');
+ });
+ $('.privilege-table-container').on('click', '[data-action="copyToAllGroup"]', function () {
+ var groupName = $(this).parents('[data-group-name]').attr('data-group-name');
+ Privileges.copyPrivilegesToAllCategories(cid, groupName);
+ });
Privileges.exposeAssumedPrivileges();
};
@@ -168,18 +189,18 @@ define('admin/manage/privileges', [
});
};
- Privileges.copyPrivilegesToChildren = function () {
- socket.emit('admin.categories.copyPrivilegesToChildren', cid, function (err) {
+ Privileges.copyPrivilegesToChildren = function (cid, group) {
+ socket.emit('admin.categories.copyPrivilegesToChildren', { cid: cid, group: group }, function (err) {
if (err) {
return app.alertError(err.message);
}
- app.alertSuccess('Privileges copied!');
+ app.alertSuccess('[[admin/manage/categories:privileges.copy-success]]');
});
};
- Privileges.copyPrivilegesFromCategory = function () {
+ Privileges.copyPrivilegesFromCategory = function (cid, group) {
categorySelector.modal(ajaxify.data.categories.slice(1), function (fromCid) {
- socket.emit('admin.categories.copyPrivilegesFrom', { toCid: cid, fromCid: fromCid }, function (err) {
+ socket.emit('admin.categories.copyPrivilegesFrom', { toCid: cid, fromCid: fromCid, group: group }, function (err) {
if (err) {
return app.alertError(err.message);
}
@@ -188,5 +209,14 @@ define('admin/manage/privileges', [
});
};
+ Privileges.copyPrivilegesToAllCategories = function (cid, group) {
+ socket.emit('admin.categories.copyPrivilegesToAllCategories', { cid: cid, group: group }, function (err) {
+ if (err) {
+ return app.alertError(err.message);
+ }
+ app.alertSuccess('[[admin/manage/categories:privileges.copy-success]]');
+ });
+ };
+
return Privileges;
});
diff --git a/public/src/ajaxify.js b/public/src/ajaxify.js
index d8753b9a9f..7e0931511e 100644
--- a/public/src/ajaxify.js
+++ b/public/src/ajaxify.js
@@ -196,7 +196,9 @@ $(document).ready(function () {
$('#content, #footer').removeClass('ajaxifying');
+ // Only executed on ajaxify. Otherwise these'd be in ajaxify.end()
app.refreshTitle(data.title);
+ app.updateTags();
});
});
}
diff --git a/public/src/app.js b/public/src/app.js
index 9ca5678f4f..1772f63e23 100644
--- a/public/src/app.js
+++ b/public/src/app.js
@@ -864,4 +864,68 @@ app.cacheBuster = null;
document.head.appendChild(linkEl);
};
+
+ app.updateTags = function () {
+ var metaWhitelist = ['title', 'description', /og:.+/, /article:.+/].map(function (val) {
+ return new RegExp(val);
+ });
+ var linkWhitelist = ['canonical', 'alternate', 'up'];
+
+ // Delete the old meta tags
+ Array.prototype.slice
+ .call(document.querySelectorAll('head meta'))
+ .filter(function (el) {
+ var name = el.getAttribute('property') || el.getAttribute('name');
+ return metaWhitelist.some(function (exp) {
+ return !!exp.test(name);
+ });
+ })
+ .forEach(function (el) {
+ document.head.removeChild(el);
+ });
+
+ // Add new meta tags
+ ajaxify.data._header.tags.meta
+ .filter(function (tagObj) {
+ var name = tagObj.name || tagObj.property;
+ return metaWhitelist.some(function (exp) {
+ return !!exp.test(name);
+ });
+ })
+ .forEach(function (tagObj) {
+ var metaEl = document.createElement('meta');
+ Object.keys(tagObj).forEach(function (prop) {
+ metaEl.setAttribute(prop, tagObj[prop]);
+ });
+ document.head.appendChild(metaEl);
+ });
+
+ // Delete the old link tags
+ Array.prototype.slice
+ .call(document.querySelectorAll('head link'))
+ .filter(function (el) {
+ var name = el.getAttribute('rel');
+ return linkWhitelist.some(function (item) {
+ return item === name;
+ });
+ })
+ .forEach(function (el) {
+ document.head.removeChild(el);
+ });
+
+ // Add new link tags
+ ajaxify.data._header.tags.link
+ .filter(function (tagObj) {
+ return linkWhitelist.some(function (item) {
+ return item === tagObj.rel;
+ });
+ })
+ .forEach(function (tagObj) {
+ var linkEl = document.createElement('link');
+ Object.keys(tagObj).forEach(function (prop) {
+ linkEl.setAttribute(prop, tagObj[prop]);
+ });
+ document.head.appendChild(linkEl);
+ });
+ };
}());
diff --git a/src/categories/create.js b/src/categories/create.js
index 4836db2d0b..3c1c23a354 100644
--- a/src/categories/create.js
+++ b/src/categories/create.js
@@ -208,18 +208,28 @@ module.exports = function (Categories) {
], callback);
}
- Categories.copyPrivilegesFrom = function (fromCid, toCid, callback) {
+ Categories.copyPrivilegesFrom = function (fromCid, toCid, group, callback) {
+ if (typeof group === 'function') {
+ callback = group;
+ group = '';
+ }
+
async.waterfall([
function (next) {
plugins.fireHook('filter:categories.copyPrivilegesFrom', {
privileges: privileges.privilegeList.slice(),
fromCid: fromCid,
toCid: toCid,
+ group: group,
}, next);
},
function (data, next) {
async.each(data.privileges, function (privilege, next) {
- copyPrivilege(privilege, data.fromCid, data.toCid, next);
+ if (group) {
+ copyPrivilegeByGroup(privilege, data.fromCid, data.toCid, group, next);
+ } else {
+ copyPrivilege(privilege, data.fromCid, data.toCid, next);
+ }
}, next);
},
], callback);
@@ -249,4 +259,22 @@ module.exports = function (Categories) {
},
], callback);
}
+
+ function copyPrivilegeByGroup(privilege, fromCid, toCid, group, callback) {
+ async.waterfall([
+ function (next) {
+ groups.leave('cid:' + toCid + ':privileges:' + privilege, group, next);
+ },
+ function (next) {
+ db.isSortedSetMember('group:cid:' + fromCid + ':privileges:' + privilege + ':members', group, next);
+ },
+ function (isMember, next) {
+ if (!isMember) {
+ return callback();
+ }
+
+ groups.join('cid:' + toCid + ':privileges:' + privilege, group, next);
+ },
+ ], callback);
+ }
};
diff --git a/src/middleware/header.js b/src/middleware/header.js
index 5bdab71f55..b347723ddb 100644
--- a/src/middleware/header.js
+++ b/src/middleware/header.js
@@ -107,7 +107,6 @@ module.exports = function (middleware) {
});
},
navigation: async.apply(navigation.get, req.uid),
- tags: async.apply(meta.tags.parse, req, data, res.locals.metaTags, res.locals.linkTags),
banned: async.apply(user.bans.isBanned, req.uid),
banReason: async.apply(user.bans.getReason, req.uid),
@@ -180,8 +179,8 @@ module.exports = function (middleware) {
templateValues.browserTitle = results.browserTitle;
templateValues.navigation = results.navigation;
templateValues.unreadCount = unreadCount;
- templateValues.metaTags = results.tags.meta;
- templateValues.linkTags = results.tags.link;
+ templateValues.metaTags = data._header.tags.meta;
+ templateValues.linkTags = data._header.tags.link;
templateValues.isAdmin = results.user.isAdmin;
templateValues.isGlobalMod = results.user.isGlobalMod;
templateValues.showModMenu = results.user.isAdmin || results.user.isGlobalMod || results.user.isMod;
diff --git a/src/middleware/render.js b/src/middleware/render.js
index 56ee550504..c33d6a8eac 100644
--- a/src/middleware/render.js
+++ b/src/middleware/render.js
@@ -6,6 +6,7 @@ var validator = require('validator');
var winston = require('winston');
var plugins = require('../plugins');
+var meta = require('../meta');
var translator = require('../translator');
var widgets = require('../widgets');
var utils = require('../utils');
@@ -49,6 +50,14 @@ module.exports = function (middleware) {
templateToRender = data.templateData.templateToRender || template;
plugins.fireHook('filter:middleware.render', { req: req, res: res, templateData: data.templateData }, next);
},
+ function parseTags(data, next) {
+ meta.tags.parse(req, data, res.locals.metaTags, res.locals.linkTags, function (err, tags) {
+ options._header = {
+ tags: tags,
+ };
+ next(err, data);
+ });
+ },
function (data, next) {
options = data.templateData;
diff --git a/src/notifications.js b/src/notifications.js
index b2078d2928..27b1fb0439 100644
--- a/src/notifications.js
+++ b/src/notifications.js
@@ -241,6 +241,11 @@ function pushToUids(uids, notification, callback) {
}
function sendEmail(uids, callback) {
+ // Update CTA messaging (as not all notification types need custom text)
+ if (['new-reply', 'new-chat'].includes(notification.type)) {
+ notification['cta-type'] = notification.type;
+ }
+
async.eachLimit(uids, 3, function (uid, next) {
emailer.send('notification', uid, {
path: notification.path,
diff --git a/src/socket.io/admin.js b/src/socket.io/admin.js
index a8c0537e20..eee514384d 100644
--- a/src/socket.io/admin.js
+++ b/src/socket.io/admin.js
@@ -279,8 +279,8 @@ SocketAdmin.email.test = function (socket, data, callback) {
function (next) {
notifications.create({
type: 'test',
- bodyShort: '[[admin-settings-email:testing]]',
- bodyLong: '[[admin-settings-email:testing.send-help]]',
+ bodyShort: '[[email:notif.test.short]]',
+ bodyLong: '[[email:notif.test.long]]',
nid: 'uid:' + socket.uid + ':test',
path: '/',
from: socket.uid,
diff --git a/src/socket.io/admin/categories.js b/src/socket.io/admin/categories.js
index d585318f17..9497abed61 100644
--- a/src/socket.io/admin/categories.js
+++ b/src/socket.io/admin/categories.js
@@ -101,25 +101,25 @@ Categories.getPrivilegeSettings = function (socket, cid, callback) {
}
};
-Categories.copyPrivilegesToChildren = function (socket, cid, callback) {
+Categories.copyPrivilegesToChildren = function (socket, data, callback) {
async.waterfall([
function (next) {
- categories.getChildren([cid], socket.uid, next);
+ categories.getChildren([data.cid], socket.uid, next);
},
function (children, next) {
children = children[0];
async.eachSeries(children, function (child, next) {
- copyPrivilegesToChildrenRecursive(cid, child, next);
+ copyPrivilegesToChildrenRecursive(data.cid, child, data.group, next);
}, next);
},
], callback);
};
-function copyPrivilegesToChildrenRecursive(parentCid, category, callback) {
+function copyPrivilegesToChildrenRecursive(parentCid, category, group, callback) {
async.waterfall([
function (next) {
- categories.copyPrivilegesFrom(parentCid, category.cid, next);
+ categories.copyPrivilegesFrom(parentCid, category.cid, group, next);
},
function (next) {
async.eachSeries(category.children, function (child, next) {
@@ -134,5 +134,19 @@ Categories.copySettingsFrom = function (socket, data, callback) {
};
Categories.copyPrivilegesFrom = function (socket, data, callback) {
- categories.copyPrivilegesFrom(data.fromCid, data.toCid, callback);
+ categories.copyPrivilegesFrom(data.fromCid, data.toCid, data.group, callback);
+};
+
+Categories.copyPrivilegesToAllCategories = function (socket, data, callback) {
+ async.waterfall([
+ function (next) {
+ categories.getAllCidsFromSet('categories:cid', next);
+ },
+ function (cids, next) {
+ cids = cids.filter(cid => parseInt(cid, 10) !== parseInt(data.cid, 10));
+ async.eachSeries(cids, function (toCid, next) {
+ categories.copyPrivilegesFrom(data.cid, toCid, data.group, next);
+ }, next);
+ },
+ ], callback);
};
diff --git a/src/views/admin/partials/categories/privileges.tpl b/src/views/admin/partials/categories/privileges.tpl
index 9e0b8632d2..be5d892545 100644
--- a/src/views/admin/partials/categories/privileges.tpl
+++ b/src/views/admin/partials/categories/privileges.tpl
@@ -94,7 +94,18 @@
{privileges.groups.name}
-