Merge remote-tracking branch 'origin/master' into develop

v1.18.x
Julian Lam 7 years ago
commit 9cbf1597cd

@ -37,7 +37,7 @@ var winston = require('winston');
var path = require('path');
var pkg = require('./package.json');
var file = require('./src/file');
var debug = require('./src/meta/debugParams')().execArgv.length;
var debug = require('./src/meta/debugFork').debugging;
global.env = process.env.NODE_ENV || 'production';

@ -2,7 +2,7 @@
"name": "nodebb",
"license": "GPL-3.0",
"description": "NodeBB Forum",
"version": "1.6.0",
"version": "1.6.1",
"homepage": "http://www.nodebb.org",
"repository": {
"type": "git",
@ -65,11 +65,11 @@
"nodebb-plugin-soundpack-default": "1.0.0",
"nodebb-plugin-spam-be-gone": "0.5.1",
"nodebb-rewards-essentials": "0.0.9",
"nodebb-theme-lavender": "4.1.0",
"nodebb-theme-persona": "6.1.1",
"nodebb-theme-lavender": "4.1.1",
"nodebb-theme-persona": "6.1.3",
"nodebb-theme-slick": "1.1.1",
"nodebb-theme-vanilla": "7.1.0",
"nodebb-widget-essentials": "3.0.6",
"nodebb-theme-vanilla": "7.1.2",
"nodebb-widget-essentials": "3.0.7",
"nodemailer": "4.1.1",
"passport": "^0.4.0",
"passport-local": "1.0.0",

@ -15,10 +15,10 @@
"smtp-transport.gmail-warning2": "Další informace o tomto řešení, <a href=\"https://nodemailer.com/usage/using-gmail/\">konzultujte s NodeMailer.</a>Alternativou je použití e-mailového rozšíření třetích stran jako je SendGrid, Mailgun atd.<a href=\"{config.relative_path}/admin/extend/plugins\">Dostupné rozšíření zde</a>.",
"smtp-transport.host": "Hostitel SMTP",
"smtp-transport.port": "Port SMTP",
"smtp-transport.security": "Connection security",
"smtp-transport.security-encrypted": "Encrypted",
"smtp-transport.security": "Zabezpečení připojení",
"smtp-transport.security-encrypted": "Šifrované",
"smtp-transport.security-starttls": "StartTLS",
"smtp-transport.security-none": "None",
"smtp-transport.security-none": "Nic",
"smtp-transport.username": "Uživatelské jméno",
"smtp-transport.username-help": "<b>Pro službu Gmail,</b> zadejte plnou e-mailovou adresu, zvláště, používáte-li spravovanou doménu Google Apps.",
"smtp-transport.password": "Heslo",

@ -3,7 +3,9 @@
"enable": "Paginate topics and posts instead of using infinite scroll.",
"topics": "Topic Pagination",
"posts-per-page": "Posts per Page",
"max-posts-per-page": "Maximum posts per page",
"categories": "Category Pagination",
"topics-per-page": "Topics per Page",
"max-topics-per-page": "Maximum topics per page",
"initial-num-load": "Initial Number of Topics to Load on Unread, Recent, and Popular"
}

@ -102,6 +102,7 @@
"paginate_description" : "Paginate topics and posts instead of using infinite scroll",
"topics_per_page": "Topics per Page",
"posts_per_page": "Posts per Page",
"max_items_per_page": "Maximum %1",
"notification_sounds" : "Play a sound when you receive a notification",
"notifications_and_sounds": "Notifications & Sounds",

@ -5,20 +5,20 @@
"from": "Nom de lexpéditeur",
"from-help": "Le nom de lexpéditeur à afficher dans l'e-mail",
"smtp-transport": "SMTP Transport",
"smtp-transport": "Protocole SMTP",
"smtp-transport.enabled": "Utiliser un server extérieur pour envoyer les emails",
"smtp-transport-help": "Vous pouvez sélectionner depuis une liste de services ou entrer un service personnalisé.",
"smtp-transport.service": "Sélectionner un service",
"smtp-transport.service-custom": "Service personnalisé",
"smtp-transport.service-help": "S",
"smtp-transport.gmail-warning1": "There have been reports of the Gmail service not working on accounts with heightened security. In those scenarios, you will have to <a href=\"https://www.google.com/settings/security/lesssecureapps\">configure your GMail account to allow less secure apps</a>.",
"smtp-transport.gmail-warning2": "For more information about this workaround, <a href=\"https://nodemailer.com/usage/using-gmail/\">please consult this NodeMailer article on the issue.</a> An alternative would be to utilise a third-party emailer plugin such as SendGrid, Mailgun, etc. <a href=\"{config.relative_path}/admin/extend/plugins\">Browse available plugins here</a>.",
"smtp-transport.service-help": "Sélectionner un service ci-dessus afin de renseigner les champs. Sinon, sélectionner \"Service Personnalisé\" et ajouter les informations ci-dessous.",
"smtp-transport.gmail-warning1": "Vous pouvez rencontrer des difficultés avec le service Gmail pour les comptes ayant une sécurité élevée. Dans ce cas, vous devez configurer <a href=\"https://www.google.com/settings/security/lesssecureapps\">votre compte Gmail pour qu'il autorise les applications moins sécurisées</a>.",
"smtp-transport.gmail-warning2": "Pour plus d'informations à propos de cette solution, <a href=\"https://nodemailer.com/usage/using-gmail/\">consulter l'article sur le NodeMailer sur ce sujet.</a> Une alternative est d'utiliser un service tiers d'envoi d'email tels que SendGrid, Mailgun, etc. <a href=\"{config.relative_path}/admin/extend/plugins\">Consulter les plugins disponibles ici</a>.",
"smtp-transport.host": "Host SMTP",
"smtp-transport.port": "Port SMTP",
"smtp-transport.security": "Connection security",
"smtp-transport.security-encrypted": "Encrypted",
"smtp-transport.security": "Accès sécurisé",
"smtp-transport.security-encrypted": "Cryptage",
"smtp-transport.security-starttls": "StartTLS",
"smtp-transport.security-none": "None",
"smtp-transport.security-none": "Aucun",
"smtp-transport.username": "Nom d'utilisateur",
"smtp-transport.username-help": "<b>Pour Gmail,</b> entrer ladresse e-mail complète ici, surtout si vous utilisez un domaine géré par Google Apps.",
"smtp-transport.password": "Mot de passe",

@ -2,8 +2,8 @@
"site-settings": "Réglages du site",
"title": "Titre du site",
"title.url": "URL",
"title.url-placeholder": "The URL of the site title",
"title.url-help": "When the title is clicked, send users to this address. If left blank, user will be sent to the forum index.",
"title.url-placeholder": "URL du titre du site",
"title.url-help": "Adresse à laquelle l'utilisateur est renvoyé lors du clic sur le titre. Si ce champ est vide, l'adresse est celle de l'index du forum.",
"title.name": "Nom de votre communauté",
"title.show-in-header": "Afficher le titre du site dans l'en-tête",
"browser-title": "Titre dans le navigateur",

@ -6,8 +6,8 @@
"sorting.most-votes": "Avec le plus de votes",
"sorting.topic-default": "Tri des sujets par défaut",
"restrictions": "Restrictions d'envoi",
"restrictions.post-queue": "Enable post queue",
"restrictions.post-queue-help": "Enabling post queue will put the posts of new users in a queue for approval.",
"restrictions.post-queue": "Activer la file d'attente des messages",
"restrictions.post-queue-help": "Activer la file d'attente des messages mettra automatiquement les messages des nouveaux utilisateurs dans la liste pour approbation.",
"restrictions.seconds-between": "Nombre de secondes entre chaque message",
"restrictions.seconds-between-new": "Nombre de secondes entre chaque message pour les nouveaux utilisateurs",
"restrictions.rep-threshold": "Seuil de réputation avant que cette restriction soit levée",

@ -4,7 +4,7 @@
"not-logged-in": "Vous ne semblez pas être connecté.",
"account-locked": "Votre compte a été temporairement suspendu",
"search-requires-login": "Rechercher nécessite d'avoir un compte. Veuillez vous identifier ou vous enregistrer.",
"goback": "Press back to return to the previous page",
"goback": "Appuyez sur retour pour revenir à la page précédente",
"invalid-cid": "ID de catégorie invalide",
"invalid-tid": "ID de sujet invalide",
"invalid-pid": "ID de message invalide",

@ -41,7 +41,7 @@
"new_register": "<strong>%1</strong> a envoyé une demande d'incription.",
"new_register_multiple": "<strong>%1</strong> inscription(s) est en attente de validation.",
"flag_assigned_to_you": "<strong>Drapeau %1</strong> vous a été assigné",
"post_awaiting_review": "Post awaiting review",
"post_awaiting_review": "Message en attente de validation",
"email-confirmed": "Email vérifié",
"email-confirmed-message": "Merci pour la validation de votre adresse email. Votre compte est désormais activé.",
"email-confirm-error-message": "Il y a un un problème dans la vérification de votre adresse email. Le code est peut être invalide ou a expiré.",

@ -9,7 +9,7 @@
"moderator-tools": "Outils de modération",
"flagged-content": "Contenu signalé",
"ip-blacklist": "Liste noire d'adresses IP",
"post-queue": "Post Queue",
"post-queue": "File d'attente des messages",
"users/online": "Utilisateurs en ligne",
"users/latest": "Derniers inscrits",
"users/sort-posts": "Utilisateurs avec le plus de messages",

@ -1,7 +1,7 @@
{
"success": "Terminé",
"topic-post": "Le message a bien été envoyé.",
"post-queued": "Your post is queued for approval.",
"post-queued": "Votre message est en attente d'approbation.",
"authentication-successful": "Authentification réussie",
"settings-saved": "Paramètres enregistrés !"
}

@ -4,7 +4,7 @@
"not-logged-in": "נראה שאינך מחובר למערכת.",
"account-locked": "חשבונך נחסם באופן זמני",
"search-requires-login": "פעולת החיפוש דורשת חשבון - בבקשה התחבר או הרשם.",
"goback": "Press back to return to the previous page",
"goback": "לחץ back לחזרה לעמוד הקודם",
"invalid-cid": "זהוי קטגוריה שגוי",
"invalid-tid": "זהוי נושא שגוי",
"invalid-pid": "זהוי פוסט שגוי",
@ -59,7 +59,7 @@
"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-days-hours": "אתה מורשה למחוק פוסט רק %1 ימים ו %2 שעות אחרי פרסומו",
"cant-delete-topic-has-reply": "אינך יכול למחוק נושא אחרי שכבר הגיבו בו.",
"cant-delete-topic-has-replies": "לא ניתן למחוק את הנושא לאחר שקיבל %1 תגובות",
"content-too-short": "אנא הכנס פוסט ארוך יותר. פוסטים חייבים להכיל לפחות %1 תווים.",

@ -41,7 +41,7 @@
"new_register": "<strong>%1</strong> שלח בקשת הרשמה.",
"new_register_multiple": "ישנן <strong>%1</strong> בקשות הרשמה שמחכות לבדיקה.",
"flag_assigned_to_you": "<strong>דיווח %1</strong> הוקצה עבורך",
"post_awaiting_review": "Post awaiting review",
"post_awaiting_review": "הפוסט ממתין לאישור",
"email-confirmed": "כתובת המייל אושרה",
"email-confirmed-message": "תודה שאישרת את כתובת המייל שלך. החשבון שלך פעיל כעת.",
"email-confirm-error-message": "אירעה שגיאה בעת אישור המייל שלך. ייתכן כי הקוד היה שגוי או פג תוקף.",

@ -6,10 +6,10 @@
"popular-month": "נושאים חמים החודש",
"popular-alltime": "הנושאים החמים בכל הזמנים",
"recent": "נושאים אחרונים",
"moderator-tools": "Moderator Tools",
"moderator-tools": "כלי מודרטור",
"flagged-content": "תוכן מדווח",
"ip-blacklist": "רשימת IP שחורה",
"post-queue": "Post Queue",
"post-queue": "פוסטים ממתינים",
"users/online": "משתמשים מחוברים",
"users/latest": "משתמשים אחרונים",
"users/sort-posts": "משתמשים עם המונה הגבוה ביותר",

@ -1,7 +1,7 @@
{
"success": "הצלחה",
"topic-post": "העלת פוסט בהצלחה.",
"post-queued": "Your post is queued for approval.",
"post-queued": "הפוסט שלך ממתין לאישור.",
"authentication-successful": "הנתונים אומתו בהצלחה",
"settings-saved": "הנתונים נשמרו!"
}

@ -59,7 +59,7 @@
"thread_tools.unlock": "הסר נעילה",
"thread_tools.move": "הזז נושא",
"thread_tools.move_all": "הזז הכל",
"thread_tools.select_category": "Select Category",
"thread_tools.select_category": "בחר קטגוריה",
"thread_tools.fork": "שכפל נושא",
"thread_tools.delete": "מחק נושא",
"thread_tools.delete-posts": "מחק פוסטים",
@ -75,9 +75,9 @@
"load_categories": "טוען קטגוריות",
"confirm_move": "הזז",
"confirm_fork": "שכפל",
"bookmark": "Bookmark",
"bookmarks": "Bookmarks",
"bookmarks.has_no_bookmarks": "You haven't bookmarked any posts yet.",
"bookmark": "הוסף למועדפים",
"bookmarks": "מועדפים",
"bookmarks.has_no_bookmarks": "לא צירפת אף פוסט למועדפים עדיין",
"loading_more_posts": "טוען פוסטים נוספים",
"move_topic": "הזז נושא",
"move_topics": "הזז נושאים",

@ -15,10 +15,10 @@
"smtp-transport.gmail-warning2": "Para mais informação sobre este workaround, <a href=\"https://nodemailer.com/usage/using-gmail/\">por gentileza consulte este artigo no NodeMailer sobre o assunto..</a> Uma alternativa seria utilizar um plugin de email terceirizado como o SendGrid, Maigun etc. . <a href=\"{config.relative_path}/admin/extend/plugins\">Explore pelos plugins disponíveis aqui</a>.",
"smtp-transport.host": "Host SMTP",
"smtp-transport.port": "Porta SMTP",
"smtp-transport.security": "Connection security",
"smtp-transport.security-encrypted": "Encrypted",
"smtp-transport.security": "Segurança da conexão",
"smtp-transport.security-encrypted": "Encriptada",
"smtp-transport.security-starttls": "StartTLS",
"smtp-transport.security-none": "None",
"smtp-transport.security-none": "Nenhuma",
"smtp-transport.username": "Nome de usuário",
"smtp-transport.username-help": "<b>Para o serviço do Gmail,</b> entre com o endereço de email completo aqui, especiamente se você estiver usando um domínio administrado pelo Google Apps.",
"smtp-transport.password": "Senha",

@ -6,8 +6,8 @@
"from-help": "用于邮件中显示的发送者",
"smtp-transport": "SMTP 通信",
"smtp-transport.enabled": "使用一个外部邮箱系统来发送邮件",
"smtp-transport-help": "可以从列表中选取一个已知的服务或自定义。",
"smtp-transport.enabled": "使用一个外部电子邮箱系统来发送邮件",
"smtp-transport-help": "可以从列表中选取一个已知的服务或自定义。",
"smtp-transport.service": "选择服务",
"smtp-transport.service-custom": "自定义",
"smtp-transport.service-help": "选取一个上方服务以便使用已知的信息。此外,还可以选取 “自定义”并在下方输入配置细节。",
@ -20,7 +20,7 @@
"smtp-transport.security-starttls": "StartTLS",
"smtp-transport.security-none": "None",
"smtp-transport.username": "用户名",
"smtp-transport.username-help": "<b>对于Gmail服务</b>请在这里输入完整的电子邮件地址,尤其是如果你使用的是 Google Apps 托管的域名。",
"smtp-transport.username-help": "<b>对于Gmail服务</b>请在这里输入完整的电子邮箱地址,尤其是如果您使用的是 Google Apps 托管的域名。",
"smtp-transport.password": "密码",
"template": "编辑电子邮件模板",

@ -1,7 +1,7 @@
'use strict';
define('pictureCropper', ['translator', 'cropper', 'benchpress'], function (translator, cropper, Benchpress) {
define('pictureCropper', ['translator', 'cropper', 'benchpress'], function (translator, Cropper, Benchpress) {
var module = {};
module.show = function (data, callback) {
@ -46,7 +46,7 @@ define('pictureCropper', ['translator', 'cropper', 'benchpress'], function (tran
var img = document.getElementById('cropped-image');
$(img).css('max-height', cropBoxHeight);
var cropperTool = new cropper.default(img, {
var cropperTool = new Cropper(img, {
aspectRatio: data.aspectRatio,
autoCropArea: 1,
viewMode: 1,
@ -122,7 +122,7 @@ define('pictureCropper', ['translator', 'cropper', 'benchpress'], function (tran
$(this).addClass('disabled');
cropperTool.destroy();
cropperTool = new cropper.default(img, {
cropperTool = new Cropper(img, {
viewMode: 1,
autoCropArea: 1,
ready: function () {

@ -12,9 +12,7 @@ var db = require('../../database');
var helpers = require('../helpers');
var accountHelpers = require('./helpers');
var settingsController = {};
var settingsController = module.exports;
settingsController.get = function (req, res, callback) {
var userData;
@ -91,67 +89,64 @@ settingsController.get = function (req, res, callback) {
next(err, data);
});
},
function (data, next) {
function (data) {
userData.customSettings = data.customSettings;
userData.disableEmailSubscriptions = parseInt(meta.config.disableEmailSubscriptions, 10) === 1;
next();
userData.dailyDigestFreqOptions = [
{ value: 'off', name: '[[user:digest_off]]', selected: userData.settings.dailyDigestFreq === 'off' },
{ value: 'day', name: '[[user:digest_daily]]', selected: userData.settings.dailyDigestFreq === 'day' },
{ value: 'week', name: '[[user:digest_weekly]]', selected: userData.settings.dailyDigestFreq === 'week' },
{ value: 'month', name: '[[user:digest_monthly]]', selected: userData.settings.dailyDigestFreq === 'month' },
];
userData.bootswatchSkinOptions = [
{ name: 'No skin', value: 'noskin' },
{ name: 'Default', value: 'default' },
{ name: 'Cerulean', value: 'cerulean' },
{ name: 'Cosmo', value: 'cosmo' },
{ name: 'Cyborg', value: 'cyborg' },
{ name: 'Darkly', value: 'darkly' },
{ name: 'Flatly', value: 'flatly' },
{ name: 'Journal', value: 'journal' },
{ name: 'Lumen', value: 'lumen' },
{ name: 'Paper', value: 'paper' },
{ name: 'Readable', value: 'readable' },
{ name: 'Sandstone', value: 'sandstone' },
{ name: 'Simplex', value: 'simplex' },
{ name: 'Slate', value: 'slate' },
{ name: 'Spacelab', value: 'spacelab' },
{ name: 'Superhero', value: 'superhero' },
{ name: 'United', value: 'united' },
{ name: 'Yeti', value: 'yeti' },
];
userData.bootswatchSkinOptions.forEach(function (skin) {
skin.selected = skin.value === userData.settings.bootswatchSkin;
});
userData.languages.forEach(function (language) {
language.selected = language.code === userData.settings.userLang;
});
userData.disableCustomUserSkins = parseInt(meta.config.disableCustomUserSkins, 10) === 1;
userData.allowUserHomePage = parseInt(meta.config.allowUserHomePage, 10) === 1;
userData.hideFullname = parseInt(meta.config.hideFullname, 10) === 1;
userData.hideEmail = parseInt(meta.config.hideEmail, 10) === 1;
userData.inTopicSearchAvailable = plugins.hasListeners('filter:topic.search');
userData.maxTopicsPerPage = parseInt(meta.config.maxTopicsPerPage, 10) || 20;
userData.maxPostsPerPage = parseInt(meta.config.maxPostsPerPage, 10) || 20;
userData.title = '[[pages:account/settings]]';
userData.breadcrumbs = helpers.buildBreadcrumbs([{ text: userData.username, url: '/user/' + userData.userslug }, { text: '[[user:settings]]' }]);
res.render('account/settings', userData);
},
], function (err) {
if (err) {
return callback(err);
}
userData.dailyDigestFreqOptions = [
{ value: 'off', name: '[[user:digest_off]]', selected: userData.settings.dailyDigestFreq === 'off' },
{ value: 'day', name: '[[user:digest_daily]]', selected: userData.settings.dailyDigestFreq === 'day' },
{ value: 'week', name: '[[user:digest_weekly]]', selected: userData.settings.dailyDigestFreq === 'week' },
{ value: 'month', name: '[[user:digest_monthly]]', selected: userData.settings.dailyDigestFreq === 'month' },
];
userData.bootswatchSkinOptions = [
{ name: 'No skin', value: 'noskin' },
{ name: 'Default', value: 'default' },
{ name: 'Cerulean', value: 'cerulean' },
{ name: 'Cosmo', value: 'cosmo' },
{ name: 'Cyborg', value: 'cyborg' },
{ name: 'Darkly', value: 'darkly' },
{ name: 'Flatly', value: 'flatly' },
{ name: 'Journal', value: 'journal' },
{ name: 'Lumen', value: 'lumen' },
{ name: 'Paper', value: 'paper' },
{ name: 'Readable', value: 'readable' },
{ name: 'Sandstone', value: 'sandstone' },
{ name: 'Simplex', value: 'simplex' },
{ name: 'Slate', value: 'slate' },
{ name: 'Spacelab', value: 'spacelab' },
{ name: 'Superhero', value: 'superhero' },
{ name: 'United', value: 'united' },
{ name: 'Yeti', value: 'yeti' },
];
userData.bootswatchSkinOptions.forEach(function (skin) {
skin.selected = skin.value === userData.settings.bootswatchSkin;
});
userData.languages.forEach(function (language) {
language.selected = language.code === userData.settings.userLang;
});
userData.disableCustomUserSkins = parseInt(meta.config.disableCustomUserSkins, 10) === 1;
userData.allowUserHomePage = parseInt(meta.config.allowUserHomePage, 10) === 1;
userData.hideFullname = parseInt(meta.config.hideFullname, 10) === 1;
userData.hideEmail = parseInt(meta.config.hideEmail, 10) === 1;
userData.inTopicSearchAvailable = plugins.hasListeners('filter:topic.search');
userData.title = '[[pages:account/settings]]';
userData.breadcrumbs = helpers.buildBreadcrumbs([{ text: userData.username, url: '/user/' + userData.userslug }, { text: '[[user:settings]]' }]);
res.render('account/settings', userData);
});
], callback);
};

@ -187,8 +187,11 @@ function addTags(categoryData, res) {
];
if (categoryData.backgroundImage) {
if (!categoryData.backgroundImage.startsWith('http')) {
categoryData.backgroundImage = nconf.get('url') + categoryData.backgroundImage;
}
res.locals.metaTags.push({
name: 'og:image',
property: 'og:image',
content: categoryData.backgroundImage,
});
}

@ -390,8 +390,10 @@ Controllers.manifest = function (req, res) {
Controllers.outgoing = function (req, res, next) {
var url = req.query.url || '';
var allowedProtocols = ['http', 'https', 'ftp', 'ftps', 'mailto', 'news', 'irc', 'gopher', 'nntp', 'feed', 'telnet', 'mms', 'rtsp', 'svn', 'tel', 'fax', 'xmpp', 'webcal'];
var parsed = require('url').parse(url);
if (!url) {
if (!url || !allowedProtocols.includes(parsed.protocol.slice(0, -1))) {
return next();
}

@ -227,6 +227,8 @@ function addTags(topicData, req, res) {
var ogImageUrl = '';
if (topicData.thumb) {
ogImageUrl = topicData.thumb;
} else if (topicData.category.backgroundImage && (!postAtIndex || !postAtIndex.index)) {
ogImageUrl = topicData.category.backgroundImage;
} else if (postAtIndex && postAtIndex.user && postAtIndex.user.picture) {
ogImageUrl = postAtIndex.user.picture;
} else if (meta.config['og:image']) {

@ -0,0 +1,41 @@
'use strict';
var fork = require('child_process').fork;
var debugArg = process.execArgv.find(function (arg) {
return /^--(debug|inspect)/.test(arg);
});
var debugging = !!debugArg;
debugArg = debugArg ? debugArg.replace('-brk', '').split('=') : ['--debug', 5859];
var lastAddress = parseInt(debugArg[1], 10);
/**
* child-process.fork, but safe for use in debuggers
* @param {string} modulePath
* @param {string[]} [args]
* @param {any} [options]
*/
function debugFork(modulePath, args, options) {
var execArgv = [];
if (global.v8debug || debugging) {
lastAddress += 1;
execArgv = [debugArg[0] + '=' + lastAddress, '--nolazy'];
}
if (!Array.isArray(args)) {
options = args;
args = [];
}
options = options || {};
options = Object.assign({}, options, {
execArgv: execArgv,
});
return fork(modulePath, args, options);
}
debugFork.debugging = debugging;
module.exports = debugFork;

@ -1,16 +0,0 @@
'use strict';
module.exports = function (execArgv) {
execArgv = execArgv || process.execArgv;
var debugArg = execArgv.find(function (arg) {
return /^--(debug|inspect)/.test(arg);
});
if (global.v8debug || debugArg) {
debugArg = debugArg ? debugArg.split('=') : ['--debug', 5859];
var num = parseInt(debugArg[1], 10) + 1;
return { execArgv: [debugArg[0] + '=' + num, '--nolazy'] };
}
return { execArgv: [] };
};

@ -1,7 +1,6 @@
'use strict';
var fs = require('fs');
var childProcess = require('child_process');
var os = require('os');
var uglifyjs = require('uglify-js');
var async = require('async');
@ -11,7 +10,7 @@ var postcss = require('postcss');
var autoprefixer = require('autoprefixer');
var clean = require('postcss-clean');
var debugParams = require('./debugParams');
var fork = require('./debugFork');
var Minifier = module.exports;
@ -47,13 +46,12 @@ function getChild() {
return free.shift();
}
var forkProcessParams = debugParams();
var proc = childProcess.fork(__filename, [], Object.assign({}, forkProcessParams, {
var proc = fork(__filename, [], {
cwd: __dirname,
env: {
minifier_child: true,
},
}));
});
pool.push(proc);
return proc;

@ -79,6 +79,7 @@ module.exports = function (middleware) {
uid: 0,
username: '[[global:guest]]',
userslug: '',
fullname: '[[global:guest]]',
email: '',
picture: user.getDefaultAvatar(),
status: 'offline',

@ -1,9 +1,8 @@
'use strict';
var fork = require('child_process').fork;
var path = require('path');
var debugParams = require('./meta/debugParams');
var fork = require('./meta/debugFork');
exports.hash = function (rounds, password, callback) {
forkChild({ type: 'hash', rounds: rounds, password: password }, callback);
@ -17,7 +16,7 @@ exports.compare = function (password, hash, callback) {
};
function forkChild(message, callback) {
var child = fork(path.join(__dirname, 'bcrypt'), [], debugParams());
var child = fork(path.join(__dirname, 'bcrypt'));
child.on('message', function (msg) {
if (msg.err) {

@ -12,12 +12,21 @@ module.exports = function (Posts) {
Posts.getUserInfoForPosts = function (uids, uid, callback) {
var groupsMap = {};
var userData;
var userSettings;
async.waterfall([
function (next) {
user.getUsersFields(uids, ['uid', 'username', 'fullname', 'userslug', 'reputation', 'postcount', 'picture', 'signature', 'banned', 'status', 'lastonline', 'groupTitle'], next);
async.parallel({
userData: function (next) {
user.getUsersFields(uids, ['uid', 'username', 'fullname', 'userslug', 'reputation', 'postcount', 'picture', 'signature', 'banned', 'status', 'lastonline', 'groupTitle'], next);
},
userSettings: function (next) {
user.getMultipleUserSettings(uids, next);
},
}, next);
},
function (_userData, next) {
userData = _userData;
function (results, next) {
userData = results.userData;
userSettings = results.userSettings;
var groupTitles = userData.map(function (userData) {
return userData && userData.groupTitle;
}).filter(function (groupTitle, index, array) {
@ -38,7 +47,7 @@ module.exports = function (Posts) {
}
});
userData.forEach(function (userData) {
userData.forEach(function (userData, index) {
userData.uid = userData.uid || 0;
userData.username = userData.username || '[[global:guest]]';
userData.userslug = userData.userslug || '';
@ -48,7 +57,7 @@ module.exports = function (Posts) {
userData.picture = userData.picture || '';
userData.status = user.getStatus(userData);
userData.signature = validator.escape(String(userData.signature || ''));
userData.fullname = validator.escape(String(userData.fullname || ''));
userData.fullname = userSettings[index].showfullname ? validator.escape(String(userData.fullname || '')) : undefined;
if (parseInt(meta.config.hideFullname, 10) === 1) {
userData.fullname = undefined;
}

@ -115,6 +115,9 @@ Topics.getTopicsByTids = function (tids, uid, callback) {
users: function (next) {
user.getUsersFields(uids, ['uid', 'username', 'fullname', 'userslug', 'reputation', 'postcount', 'picture', 'signature', 'banned', 'status'], next);
},
userSettings: function (next) {
user.getMultipleUserSettings(uids, next);
},
categories: function (next) {
categories.getCategoriesFields(cids, ['cid', 'name', 'slug', 'icon', 'image', 'bgColor', 'color', 'disabled'], next);
},
@ -136,11 +139,11 @@ Topics.getTopicsByTids = function (tids, uid, callback) {
}, next);
},
function (results, next) {
if (parseInt(meta.config.hideFullname, 10) === 1) {
results.users.forEach(function (user) {
results.users.forEach(function (user, index) {
if (parseInt(meta.config.hideFullname, 10) === 1 || !results.userSettings[index].showfullname) {
user.fullname = undefined;
});
}
}
});
var users = _.zipObject(uids, results.users);
var categories = _.zipObject(cids, results.categories);

@ -45,7 +45,7 @@ module.exports = {
}
meta.configs.setMultiple({
'brand:logo': path.join(nconf.get('upload_path'), 'system', path.basename(meta.config['brand:logo'])),
'brand:logo': path.join('/assets/uploads/system', path.basename(meta.config['brand:logo'])),
'brand:emailLogo': '/assets/uploads/system/site-logo-x50.png',
}, next);
},

@ -12,7 +12,7 @@ var pubsub = require('../pubsub');
var LRU = require('lru-cache');
var cache = LRU({
max: 1000,
max: 2000,
length: function () { return 1; },
maxAge: 1000 * 60 * 60,
});
@ -135,12 +135,14 @@ module.exports = function (User) {
}
User.saveSettings = function (uid, data, callback) {
if (!data.postsPerPage || parseInt(data.postsPerPage, 10) <= 1 || parseInt(data.postsPerPage, 10) > meta.config.postsPerPage) {
return callback(new Error('[[error:invalid-pagination-value, 2, ' + meta.config.postsPerPage + ']]'));
var maxPostsPerPage = meta.config.maxPostsPerPage || 20;
if (!data.postsPerPage || parseInt(data.postsPerPage, 10) <= 1 || parseInt(data.postsPerPage, 10) > maxPostsPerPage) {
return callback(new Error('[[error:invalid-pagination-value, 2, ' + maxPostsPerPage + ']]'));
}
if (!data.topicsPerPage || parseInt(data.topicsPerPage, 10) <= 1 || parseInt(data.topicsPerPage, 10) > meta.config.topicsPerPage) {
return callback(new Error('[[error:invalid-pagination-value, 2, ' + meta.config.topicsPerPage + ']]'));
var maxTopicsPerPage = meta.config.maxTopicsPerPage || 20;
if (!data.topicsPerPage || parseInt(data.topicsPerPage, 10) <= 1 || parseInt(data.topicsPerPage, 10) > maxTopicsPerPage) {
return callback(new Error('[[error:invalid-pagination-value, 2, ' + maxTopicsPerPage + ']]'));
}
data.userLang = data.userLang || meta.config.defaultLang;
@ -153,8 +155,8 @@ module.exports = function (User) {
openOutgoingLinksInNewTab: data.openOutgoingLinksInNewTab,
dailyDigestFreq: data.dailyDigestFreq || 'off',
usePagination: data.usePagination,
topicsPerPage: Math.min(data.topicsPerPage, parseInt(meta.config.topicsPerPage, 10) || 20),
postsPerPage: Math.min(data.postsPerPage, parseInt(meta.config.postsPerPage, 10) || 20),
topicsPerPage: Math.min(data.topicsPerPage, parseInt(maxTopicsPerPage, 10) || 20),
postsPerPage: Math.min(data.postsPerPage, parseInt(maxPostsPerPage, 10) || 20),
userLang: data.userLang || meta.config.defaultLang,
followTopicsOnCreate: data.followTopicsOnCreate,
followTopicsOnReply: data.followTopicsOnReply,

@ -18,7 +18,8 @@
<div class="col-sm-2 col-xs-12 settings-header">[[admin/settings/pagination:topics]]</div>
<div class="col-sm-10 col-xs-12">
<form>
<strong>[[admin/settings/pagination:posts-per-page]]</strong><br /> <input type="text" class="form-control" value="20" data-field="postsPerPage">
<strong>[[admin/settings/pagination:posts-per-page]]</strong><br /> <input type="text" class="form-control" value="20" data-field="postsPerPage"><br/>
<strong>[[admin/settings/pagination:max-posts-per-page]]</strong><br /> <input type="text" class="form-control" value="20" data-field="maxPostsPerPage"><br/>
</form>
</div>
</div>
@ -28,6 +29,7 @@
<div class="col-sm-10 col-xs-12">
<form>
<strong>[[admin/settings/pagination:topics-per-page]]</strong><br /> <input type="text" class="form-control" value="20" data-field="topicsPerPage"><br />
<strong>[[admin/settings/pagination:max-topics-per-page]]</strong><br /> <input type="text" class="form-control" value="20" data-field="maxTopicsPerPage"><br/>
<strong>[[admin/settings/pagination:initial-num-load]]</strong><br /> <input type="text" class="form-control" value="20" data-field="topicsPerList">
</form>
</div>

@ -92,18 +92,19 @@ function renderWidget(widget, uid, options, callback) {
}
if (widget.data.container && widget.data.container.match('{body}')) {
translator.translate(widget.data.title, function (title) {
Benchpress.compileParse(widget.data.container, {
title: title,
body: html,
}, function (err, html) {
next(err, { html: html });
});
});
Benchpress.compileParse(widget.data.container, {
title: widget.data.title,
body: html,
}, next);
} else {
next(null, { html: html });
next(null, html);
}
},
function (html, next) {
translator.translate(html, function (translatedHtml) {
next(null, { html: translatedHtml });
});
},
], callback);
}

@ -216,7 +216,7 @@ describe('Controllers', function () {
});
it('should load /outgoing?url=<url>', function (done) {
request(nconf.get('url') + '/outgoing?url=http//youtube.com', function (err, res, body) {
request(nconf.get('url') + '/outgoing?url=http://youtube.com', function (err, res, body) {
assert.ifError(err);
assert.equal(res.statusCode, 200);
assert(body);
@ -233,6 +233,15 @@ describe('Controllers', function () {
});
});
it('should 404 on /outgoing with javascript: protocol', function (done) {
request(nconf.get('url') + '/outgoing?url=javascript:alert(1);', function (err, res, body) {
assert.ifError(err);
assert.equal(res.statusCode, 404);
assert(body);
done();
});
});
it('should load /tos', function (done) {
meta.config.termsOfUse = 'please accept our tos';
request(nconf.get('url') + '/tos', function (err, res, body) {

@ -276,13 +276,28 @@ describe('meta', function () {
});
});
describe('debug params', function () {
it('should return fork arguments for debug', function (done) {
var debugParams = require('../src/meta/debugParams');
var data = debugParams(['--debug=5858', '--foo=1']);
assert.equal(data.execArgv[0], '--debug=5859');
assert.equal(data.execArgv[1], '--nolazy');
describe('debugFork', function () {
var oldArgv;
before(function () {
oldArgv = process.execArgv;
process.execArgv = ['--debug=5858', '--foo=1'];
});
it('should detect debugging', function (done) {
var debugFork = require('../src/meta/debugFork');
assert(!debugFork.debugging);
var debugForkPath = require.resolve('../src/meta/debugFork');
delete require.cache[debugForkPath];
debugFork = require('../src/meta/debugFork');
assert(debugFork.debugging);
done();
});
after(function () {
process.execArgv = oldArgv;
});
});
});

Loading…
Cancel
Save