feat: #7743, webserver

v1.18.x
Barış Soner Uşaklı 6 years ago
parent 87552c559c
commit 0d047f4eb9

@ -761,3 +761,5 @@ Flags.notify = function (flagObj, uid, callback) {
break;
}
};
require('./promisify')(Flags);

@ -125,9 +125,9 @@ Plugins.reload = async function () {
});
};
Plugins.reloadRoutes = async function (router) {
Plugins.reloadRoutes = async function (params) {
var controllers = require('../controllers');
await Plugins.fireHook('static:app.load', { app: app, router: router, middleware: middleware, controllers: controllers });
await Plugins.fireHook('static:app.load', { app: app, router: params.router, middleware: middleware, controllers: controllers });
winston.verbose('[plugins] All plugins reloaded and rerouted');
};

@ -46,98 +46,89 @@ Auth.getLoginStrategies = function () {
return loginStrategies;
};
Auth.reloadRoutes = function (router, callback) {
Auth.reloadRoutes = async function (params) {
loginStrategies.length = 0;
const router = params.router;
if (plugins.hasListeners('action:auth.overrideLogin')) {
winston.warn('[authentication] Login override detected, skipping local login strategy.');
plugins.fireHook('action:auth.overrideLogin');
} else {
passport.use(new passportLocal({ passReqToCallback: true }, controllers.authentication.localLogin));
}
try {
loginStrategies = await plugins.fireHook('filter:auth.init', loginStrategies);
} catch (err) {
winston.error('[authentication] ' + err.stack);
}
async.waterfall([
function (next) {
plugins.fireHook('filter:auth.init', loginStrategies, function (err) {
loginStrategies = loginStrategies || [];
loginStrategies.forEach(function (strategy) {
if (strategy.url) {
router.get(strategy.url, Auth.middleware.applyCSRF, function (req, res, next) {
req.session.ssoState = req.csrfToken();
passport.authenticate(strategy.name, {
scope: strategy.scope,
prompt: strategy.prompt || undefined,
state: req.session.ssoState,
})(req, res, next);
});
}
router[strategy.callbackMethod || 'get'](strategy.callbackURL, function (req, res, next) {
// Ensure the passed-back state value is identical to the saved ssoState (unless explicitly skipped)
if (strategy.checkState === false) {
return next();
}
next(req.query.state !== req.session.ssoState ? new Error('[[error:csrf-invalid]]') : null);
}, function (req, res, next) {
// Trigger registration interstitial checks
req.session.registration = req.session.registration || {};
// save returnTo for later usage in /register/complete
// passport seems to remove `req.session.returnTo` after it redirects
req.session.registration.returnTo = req.session.returnTo;
next();
}, function (req, res, next) {
passport.authenticate(strategy.name, function (err, user) {
if (err) {
winston.error('[authentication] ' + err.stack);
delete req.session.registration;
return next(err);
}
next(null, loginStrategies);
});
if (!user) {
delete req.session.registration;
return helpers.redirect(res, strategy.failureUrl !== undefined ? strategy.failureUrl : '/login');
}
res.locals.user = user;
res.locals.strategy = strategy;
next();
})(req, res, next);
},
function (loginStrategies, next) {
loginStrategies = loginStrategies || [];
loginStrategies.forEach(function (strategy) {
if (strategy.url) {
router.get(strategy.url, Auth.middleware.applyCSRF, function (req, res, next) {
req.session.ssoState = req.csrfToken();
passport.authenticate(strategy.name, {
scope: strategy.scope,
prompt: strategy.prompt || undefined,
state: req.session.ssoState,
})(req, res, next);
});
Auth.middleware.validateAuth,
(req, res, next) => {
async.waterfall([
async.apply(req.login.bind(req), res.locals.user),
async.apply(controllers.authentication.onSuccessfulLogin, req, req.uid),
], function (err) {
if (err) {
return next(err);
}
router[strategy.callbackMethod || 'get'](strategy.callbackURL, function (req, res, next) {
// Ensure the passed-back state value is identical to the saved ssoState (unless explicitly skipped)
if (strategy.checkState === false) {
return next();
}
next(req.query.state !== req.session.ssoState ? new Error('[[error:csrf-invalid]]') : null);
}, function (req, res, next) {
// Trigger registration interstitial checks
req.session.registration = req.session.registration || {};
// save returnTo for later usage in /register/complete
// passport seems to remove `req.session.returnTo` after it redirects
req.session.registration.returnTo = req.session.returnTo;
next();
}, function (req, res, next) {
passport.authenticate(strategy.name, function (err, user) {
if (err) {
delete req.session.registration;
return next(err);
}
if (!user) {
delete req.session.registration;
return helpers.redirect(res, strategy.failureUrl !== undefined ? strategy.failureUrl : '/login');
}
res.locals.user = user;
res.locals.strategy = strategy;
next();
})(req, res, next);
},
Auth.middleware.validateAuth,
(req, res, next) => {
async.waterfall([
async.apply(req.login.bind(req), res.locals.user),
async.apply(controllers.authentication.onSuccessfulLogin, req, req.uid),
], function (err) {
if (err) {
return next(err);
}
helpers.redirect(res, strategy.successUrl !== undefined ? strategy.successUrl : '/');
});
});
helpers.redirect(res, strategy.successUrl !== undefined ? strategy.successUrl : '/');
});
});
});
var multipart = require('connect-multiparty');
var multipartMiddleware = multipart();
var middlewares = [multipartMiddleware, Auth.middleware.applyCSRF, Auth.middleware.applyBlacklist];
router.post('/register', middlewares, controllers.authentication.register);
router.post('/register/complete', middlewares, controllers.authentication.registerComplete);
router.post('/register/abort', controllers.authentication.registerAbort);
router.post('/login', Auth.middleware.applyCSRF, Auth.middleware.applyBlacklist, controllers.authentication.login);
router.post('/logout', Auth.middleware.applyCSRF, controllers.authentication.logout);
var multipart = require('connect-multiparty');
var multipartMiddleware = multipart();
var middlewares = [multipartMiddleware, Auth.middleware.applyCSRF, Auth.middleware.applyBlacklist];
next();
},
], callback);
router.post('/register', middlewares, controllers.authentication.register);
router.post('/register/complete', middlewares, controllers.authentication.registerComplete);
router.post('/register/abort', controllers.authentication.registerAbort);
router.post('/login', Auth.middleware.applyCSRF, Auth.middleware.applyBlacklist, controllers.authentication.login);
router.post('/logout', Auth.middleware.applyCSRF, controllers.authentication.logout);
};
passport.serializeUser(function (user, done) {

@ -3,7 +3,6 @@
var nconf = require('nconf');
var winston = require('winston');
var path = require('path');
var async = require('async');
var express = require('express');
var meta = require('../meta');
@ -90,7 +89,7 @@ function groupRoutes(app, middleware, controllers) {
setupPageRoute(app, '/groups/:slug/members', middleware, middlewares, controllers.groups.members);
}
module.exports = function (app, middleware, callback) {
module.exports = async function (app, middleware) {
const router = express.Router();
router.render = function () {
app.render.apply(app, arguments);
@ -109,21 +108,15 @@ module.exports = function (app, middleware, callback) {
// homepage handled by `action:homepage.get:[route]`
setupPageRoute(router, '/', middleware, [], controllers.home.pluginHook);
async.series([
async.apply(plugins.reloadRoutes, router),
async.apply(authRoutes.reloadRoutes, router),
async.apply(addCoreRoutes, app, router, middleware),
async.apply(user.addInterstitials),
function (next) {
winston.info('Routes added');
next();
},
], function (err) {
callback(err);
});
await plugins.reloadRoutes({ router: router });
await authRoutes.reloadRoutes({ router: router });
addCoreRoutes(app, router, middleware);
await user.addInterstitials();
winston.info('Routes added');
};
function addCoreRoutes(app, router, middleware, callback) {
function addCoreRoutes(app, router, middleware) {
adminRoutes(router, middleware, controllers);
metaRoutes(router, middleware, controllers);
apiRoutes(router, middleware, controllers);
@ -190,5 +183,4 @@ function addCoreRoutes(app, router, middleware, callback) {
app.use(controllers['404'].handle404);
app.use(controllers.errors.handleURIErrors);
app.use(controllers.errors.handleErrors);
setImmediate(callback);
}

@ -2,6 +2,7 @@
'use strict';
var fs = require('fs');
const util = require('util');
var path = require('path');
var os = require('os');
var nconf = require('nconf');
@ -65,7 +66,7 @@ server.on('connection', function (conn) {
});
});
module.exports.destroy = function (callback) {
exports.destroy = function (callback) {
server.close(callback);
for (var key in connections) {
if (connections.hasOwnProperty(key)) {
@ -74,76 +75,45 @@ module.exports.destroy = function (callback) {
}
};
module.exports.listen = function (callback) {
callback = callback || function () { };
exports.listen = async function () {
emailer.registerApp(app);
setupExpressApp(app);
helpers.register();
logger.init(app);
await initializeNodeBB();
winston.info('NodeBB Ready');
require('./socket.io').server.emit('event:nodebb.ready', {
'cache-buster': meta.config['cache-buster'],
hostname: os.hostname(),
});
async.waterfall([
function (next) {
setupExpressApp(app, next);
},
function (next) {
helpers.register();
logger.init(app);
initializeNodeBB(next);
},
function (next) {
winston.info('NodeBB Ready');
require('./socket.io').server.emit('event:nodebb.ready', {
'cache-buster': meta.config['cache-buster'],
hostname: os.hostname(),
});
plugins.fireHook('action:nodebb.ready');
plugins.fireHook('action:nodebb.ready');
listen(next);
},
], callback);
await util.promisify(listen)();
};
function initializeNodeBB(callback) {
var middleware = require('./middleware');
async.waterfall([
function (next) {
meta.themes.setupPaths(next);
},
function (next) {
plugins.init(app, middleware, next);
},
async.apply(plugins.fireHook, 'static:assets.prepare', {}),
function (next) {
plugins.fireHook('static:app.preload', {
app: app,
middleware: middleware,
}, next);
},
function (next) {
routes(app, middleware, next);
},
function (next) {
meta.sounds.addUploads(next);
},
function (next) {
meta.blacklist.load(next);
},
function (next) {
flags.init(next);
},
], function (err) {
callback(err);
async function initializeNodeBB() {
const middleware = require('./middleware');
await meta.themes.setupPaths();
await plugins.init(app, middleware);
await plugins.fireHook('static:assets.prepare', {});
await plugins.fireHook('static:app.preload', {
app: app,
middleware: middleware,
});
await routes(app, middleware);
await meta.sounds.addUploads();
await meta.blacklist.load();
await flags.init();
}
function setupExpressApp(app, callback) {
var middleware = require('./middleware');
var pingController = require('./controllers/ping');
function setupExpressApp(app) {
const middleware = require('./middleware');
const pingController = require('./controllers/ping');
var relativePath = nconf.get('relative_path');
var viewsDir = nconf.get('views_dir');
const relativePath = nconf.get('relative_path');
const viewsDir = nconf.get('views_dir');
app.engine('tpl', function (filepath, data, next) {
filepath = filepath.replace(/\.tpl$/, '.js');
@ -210,8 +180,6 @@ function setupExpressApp(app, callback) {
var toobusy = require('toobusy-js');
toobusy.maxLag(meta.config.eventLoopLagThreshold);
toobusy.interval(meta.config.eventLoopInterval);
callback();
}
function setupFavicon(app) {
@ -308,7 +276,7 @@ function listen(callback) {
}
}
module.exports.testSocket = function (socketPath, callback) {
exports.testSocket = function (socketPath, callback) {
if (typeof socketPath !== 'string') {
return callback(new Error('invalid socket path : ' + socketPath));
}
@ -337,3 +305,5 @@ module.exports.testSocket = function (socketPath, callback) {
async.apply(fs.unlink, socketPath), // The socket was stale, kick it out of the way
], callback);
};
require('./promisify')(exports);

Loading…
Cancel
Save