mirror of
https://github.com/NodeBB/NodeBB.git
synced 2026-07-06 00:07:25 +02:00
Merge remote-tracking branch 'origin/master' into develop
This commit is contained in:
@@ -89,7 +89,7 @@ function renderRoute(name, req, res, next) {
|
||||
|
||||
if (name === 'password') {
|
||||
userData.minimumPasswordLength = parseInt(meta.config.minimumPasswordLength, 10);
|
||||
userData.minimumPasswordStrength = parseInt(meta.config.minimumPasswordStrength || 0, 10);
|
||||
userData.minimumPasswordStrength = parseInt(meta.config.minimumPasswordStrength || 1, 10);
|
||||
}
|
||||
|
||||
userData.title = '[[pages:account/edit/' + name + ', ' + userData.username + ']]';
|
||||
|
||||
@@ -33,11 +33,18 @@ pluginsController.get = function (req, res, next) {
|
||||
var compatiblePkgNames = payload.compatible.map(function (pkgData) {
|
||||
return pkgData.name;
|
||||
});
|
||||
var installedPlugins = payload.compatible.filter(function (plugin) {
|
||||
return plugin && plugin.installed;
|
||||
});
|
||||
var activePlugins = payload.all.filter(function (plugin) {
|
||||
return plugin && plugin.installed && plugin.active;
|
||||
});
|
||||
|
||||
res.render('admin/extend/plugins', {
|
||||
installed: payload.compatible.filter(function (plugin) {
|
||||
return plugin.installed;
|
||||
}),
|
||||
installed: installedPlugins,
|
||||
installedCount: installedPlugins.length,
|
||||
activeCount: activePlugins.length,
|
||||
inactiveCount: Math.max(0, installedPlugins.length - activePlugins.length),
|
||||
upgradeCount: payload.compatible.reduce(function (count, current) {
|
||||
if (current.installed && current.outdated) {
|
||||
count += 1;
|
||||
|
||||
@@ -166,7 +166,7 @@ Controllers.register = function (req, res, next) {
|
||||
data.minimumUsernameLength = parseInt(meta.config.minimumUsernameLength, 10);
|
||||
data.maximumUsernameLength = parseInt(meta.config.maximumUsernameLength, 10);
|
||||
data.minimumPasswordLength = parseInt(meta.config.minimumPasswordLength, 10);
|
||||
data.minimumPasswordStrength = parseInt(meta.config.minimumPasswordStrength || 0, 10);
|
||||
data.minimumPasswordStrength = parseInt(meta.config.minimumPasswordStrength || 1, 10);
|
||||
data.termsOfUse = termsOfUse.postData.content;
|
||||
data.breadcrumbs = helpers.buildBreadcrumbs([{
|
||||
text: '[[register:register]]',
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
var os = require('os');
|
||||
|
||||
var meta = require('../meta');
|
||||
|
||||
module.exports = function (middleware) {
|
||||
@@ -15,6 +17,10 @@ module.exports = function (middleware) {
|
||||
headers['Access-Control-Allow-Origin'] = encodeURI(meta.config['access-control-allow-origin']);
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
headers['X-Upstream-Hostname'] = os.hostname();
|
||||
}
|
||||
|
||||
for (var key in headers) {
|
||||
if (headers.hasOwnProperty(key) && headers[key]) {
|
||||
res.setHeader(key, headers[key]);
|
||||
|
||||
@@ -211,7 +211,7 @@ middleware.templatesOnDemand = function (req, res, next) {
|
||||
if (!filePath.endsWith('.js')) {
|
||||
return next();
|
||||
}
|
||||
|
||||
var tplPath = filePath.replace(/\.js$/, '.tpl');
|
||||
if (workingCache[filePath]) {
|
||||
workingCache[filePath].push(next);
|
||||
return;
|
||||
@@ -234,12 +234,9 @@ middleware.templatesOnDemand = function (req, res, next) {
|
||||
}
|
||||
|
||||
workingCache[filePath] = [next];
|
||||
fs.readFile(filePath.replace(/\.js$/, '.tpl'), 'utf8', cb);
|
||||
fs.readFile(tplPath, 'utf8', cb);
|
||||
},
|
||||
function (source, cb) {
|
||||
if (!source) {
|
||||
return cb(new Error('[[error:templatesOnDemand.source-template-empty]]'));
|
||||
}
|
||||
Benchpress.precompile({
|
||||
source: source,
|
||||
minify: global.env !== 'development',
|
||||
@@ -247,7 +244,7 @@ middleware.templatesOnDemand = function (req, res, next) {
|
||||
},
|
||||
function (compiled, cb) {
|
||||
if (!compiled) {
|
||||
return cb(new Error('[[error:templatesOnDemand.compiled-template-empty]]'));
|
||||
return cb(new Error('[[error:templatesOnDemand.compiled-template-empty, ' + tplPath + ']]'));
|
||||
}
|
||||
fs.writeFile(filePath, compiled, cb);
|
||||
},
|
||||
|
||||
@@ -15,17 +15,13 @@ pubsub.on('admin:navigation:save', function () {
|
||||
|
||||
admin.save = function (data, callback) {
|
||||
var order = Object.keys(data);
|
||||
var items = data.map(function (item, idx) {
|
||||
var data = {};
|
||||
|
||||
var items = data.map(function (item) {
|
||||
for (var i in item) {
|
||||
if (item.hasOwnProperty(i)) {
|
||||
item[i] = typeof item[i] === 'string' ? translator.escape(item[i]) : item[i];
|
||||
if (item.hasOwnProperty(i) && typeof item[i] === 'string' && (i === 'title' || i === 'text')) {
|
||||
item[i] = translator.escape(item[i]);
|
||||
}
|
||||
}
|
||||
|
||||
data[idx] = item;
|
||||
return JSON.stringify(data);
|
||||
return JSON.stringify(item);
|
||||
});
|
||||
|
||||
admin.cache = null;
|
||||
@@ -53,8 +49,8 @@ admin.get = function (callback) {
|
||||
db.getSortedSetRange('navigation:enabled', 0, -1, next);
|
||||
},
|
||||
function (data, next) {
|
||||
data = data.map(function (item, idx) {
|
||||
return JSON.parse(item)[idx];
|
||||
data = data.map(function (item) {
|
||||
return JSON.parse(item);
|
||||
});
|
||||
|
||||
next(null, data);
|
||||
|
||||
@@ -38,6 +38,3 @@ navigation.get = function (callback) {
|
||||
},
|
||||
], callback);
|
||||
};
|
||||
|
||||
|
||||
module.exports = navigation;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
var os = require('os');
|
||||
var async = require('async');
|
||||
var nconf = require('nconf');
|
||||
var winston = require('winston');
|
||||
@@ -84,6 +85,7 @@ function onConnect(socket) {
|
||||
|
||||
socket.join('sess_' + socket.request.signedCookies[nconf.get('sessionKey')]);
|
||||
io.sockets.sockets[socket.id].emit('checkSession', socket.uid);
|
||||
io.sockets.sockets[socket.id].emit('setHostname', os.hostname());
|
||||
}
|
||||
|
||||
function onMessage(socket, payload) {
|
||||
|
||||
@@ -30,7 +30,7 @@ module.exports = function (Topics) {
|
||||
};
|
||||
|
||||
Topics.getTopicBookmarks = function (tid, callback) {
|
||||
db.getSortedSetRangeWithScores(['tid:' + tid + ':bookmarks'], 0, -1, callback);
|
||||
db.getSortedSetRangeWithScores('tid:' + tid + ':bookmarks', 0, -1, callback);
|
||||
};
|
||||
|
||||
Topics.updateTopicBookmarks = function (tid, pids, callback) {
|
||||
|
||||
38
src/upgrades/1.7.6/flatten_navigation_data.js
Normal file
38
src/upgrades/1.7.6/flatten_navigation_data.js
Normal file
@@ -0,0 +1,38 @@
|
||||
'use strict';
|
||||
|
||||
var async = require('async');
|
||||
var db = require('../../database');
|
||||
|
||||
module.exports = {
|
||||
name: 'Flatten navigation data',
|
||||
timestamp: Date.UTC(2018, 1, 17),
|
||||
method: function (callback) {
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
db.getSortedSetRangeWithScores('navigation:enabled', 0, -1, next);
|
||||
},
|
||||
function (data, next) {
|
||||
var order = [];
|
||||
var items = [];
|
||||
data.forEach(function (item) {
|
||||
var navItem = JSON.parse(item.value);
|
||||
var keys = Object.keys(navItem);
|
||||
if (keys.length && parseInt(keys[0], 10) >= 0) {
|
||||
navItem = navItem[keys[0]];
|
||||
}
|
||||
order.push(item.score);
|
||||
items.push(JSON.stringify(navItem));
|
||||
});
|
||||
|
||||
async.series([
|
||||
function (next) {
|
||||
db.delete('navigation:enabled', next);
|
||||
},
|
||||
function (next) {
|
||||
db.sortedSetAdd('navigation:enabled', order, items, next);
|
||||
},
|
||||
], next);
|
||||
},
|
||||
], callback);
|
||||
},
|
||||
};
|
||||
22
src/upgrades/1.7.6/update_min_pass_strength.js
Normal file
22
src/upgrades/1.7.6/update_min_pass_strength.js
Normal file
@@ -0,0 +1,22 @@
|
||||
'use strict';
|
||||
|
||||
var db = require('../../database');
|
||||
|
||||
var async = require('async');
|
||||
|
||||
module.exports = {
|
||||
name: 'Revising minimum password strength to 1 (from 0)',
|
||||
timestamp: Date.UTC(2017, 1, 21),
|
||||
method: function (callback) {
|
||||
async.waterfall([
|
||||
async.apply(db.getObjectField.bind(db), 'config', 'minimumPasswordStrength'),
|
||||
function (strength, next) {
|
||||
if (!strength) {
|
||||
return db.setObjectField('config', 'minimumPasswordStrength', 1, next);
|
||||
}
|
||||
|
||||
setImmediate(next);
|
||||
},
|
||||
], callback);
|
||||
},
|
||||
};
|
||||
@@ -106,14 +106,14 @@ Digest.send = function (data, callback) {
|
||||
function (next) {
|
||||
async.parallel({
|
||||
notifications: async.apply(user.notifications.getDailyUnread, userObj.uid),
|
||||
popular: async.apply(topics.getPopularTopics, data.interval, userObj.uid, 0, 9),
|
||||
topics: async.apply(getTermTopics, data.interval, userObj.uid, 0, 9),
|
||||
}, next);
|
||||
},
|
||||
function (data, next) {
|
||||
var notifications = data.notifications.filter(Boolean);
|
||||
|
||||
// If there are no notifications and no new topics, don't bother sending a digest
|
||||
if (!notifications.length && !data.popular.topics.length) {
|
||||
if (!notifications.length && !data.topics.length) {
|
||||
return next();
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ Digest.send = function (data, callback) {
|
||||
});
|
||||
|
||||
// Fix relative paths in topic data
|
||||
data.popular.topics = data.popular.topics.map(function (topicObj) {
|
||||
data.topics = data.topics.map(function (topicObj) {
|
||||
var user = topicObj.hasOwnProperty('teaser') && topicObj.teaser !== undefined ? topicObj.teaser.user : topicObj.user;
|
||||
if (user && user.picture && utils.isRelativeUrl(user.picture)) {
|
||||
user.picture = nconf.get('base_url') + user.picture;
|
||||
@@ -138,7 +138,7 @@ Digest.send = function (data, callback) {
|
||||
username: userObj.username,
|
||||
userslug: userObj.userslug,
|
||||
notifications: notifications,
|
||||
recent: data.popular.topics,
|
||||
recent: data.topics,
|
||||
interval: data.interval,
|
||||
showUnsubscribe: true,
|
||||
}, function (err) {
|
||||
@@ -154,4 +154,22 @@ Digest.send = function (data, callback) {
|
||||
], function (err) {
|
||||
callback(err, emailsSent);
|
||||
});
|
||||
|
||||
function getTermTopics(term, uid, start, stop, callback) {
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
topics.getPopularTopics(term, uid, start, stop, next);
|
||||
},
|
||||
function (data, next) {
|
||||
if (!data.topics.length) {
|
||||
topics.getLatestTopics(uid, start, stop, term, next);
|
||||
} else {
|
||||
next(null, data);
|
||||
}
|
||||
},
|
||||
function (data, next) {
|
||||
next(null, data.topics);
|
||||
},
|
||||
], callback);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,7 +1,16 @@
|
||||
<ul class="nav nav-pills">
|
||||
<li class="active"><a href="#installed" data-toggle="tab">[[admin/extend/plugins:installed]]</a></li>
|
||||
<li><a href="#active" data-toggle="tab">[[admin/extend/plugins:active]]</a></li>
|
||||
<li><a href="#deactive" data-toggle="tab">[[admin/extend/plugins:inactive]]</a></li>
|
||||
<li class="active"><a href="#installed" data-toggle="tab">
|
||||
[[admin/extend/plugins:installed]]
|
||||
<span class="badge">{installedCount}</span>
|
||||
</a></li>
|
||||
<li><a href="#active" data-toggle="tab">
|
||||
[[admin/extend/plugins:active]]
|
||||
<span class="badge">{activeCount}</span>
|
||||
</a></li>
|
||||
<li><a href="#deactive" data-toggle="tab">
|
||||
[[admin/extend/plugins:inactive]]
|
||||
<span class="badge">{inactiveCount}</span>
|
||||
</a></li>
|
||||
<li><a href="#upgrade" data-toggle="tab">
|
||||
[[admin/extend/plugins:out-of-date]]
|
||||
<span class="badge">{upgradeCount}</span>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var os = require('os');
|
||||
var nconf = require('nconf');
|
||||
var express = require('express');
|
||||
var app = express();
|
||||
@@ -17,6 +18,7 @@ var session = require('express-session');
|
||||
var useragent = require('express-useragent');
|
||||
var favicon = require('serve-favicon');
|
||||
var detector = require('spider-detector');
|
||||
var helmet = require('helmet');
|
||||
|
||||
var db = require('./database');
|
||||
var file = require('./file');
|
||||
@@ -73,6 +75,7 @@ module.exports.listen = function (callback) {
|
||||
|
||||
require('./socket.io').server.emit('event:nodebb.ready', {
|
||||
'cache-buster': meta.config['cache-buster'],
|
||||
hostname: os.hostname(),
|
||||
});
|
||||
|
||||
plugins.fireHook('action:nodebb.ready');
|
||||
@@ -171,6 +174,8 @@ function setupExpressApp(app, callback) {
|
||||
saveUninitialized: true,
|
||||
}));
|
||||
|
||||
app.use(helmet());
|
||||
app.use(helmet.referrerPolicy({ policy: 'strict-origin-when-cross-origin' }));
|
||||
app.use(middleware.addHeaders);
|
||||
app.use(middleware.processRender);
|
||||
auth.initialize(app, middleware);
|
||||
|
||||
Reference in New Issue
Block a user